cancel
Showing results for 
Search instead for 
Did you mean: 
Welcome to the September Hub-bub

We are inviting you to join our exciting online event where you can learn a lot of useful information, share your knowledge and have fun. Each week, we will reward the best posters with free gift cards .

Just pick any topic you like in the SwaggerHub Community, or create your own to dive into the wonderful September Hub-bub.

Event duration: September 2-27. More information.

This Week Top Contributors:

We will decide the winners next Monday

Interactive API Docs / POST body data omitted using consumes 'application/x-www-form-urlencoded'

SOLVED
Occasional Contributor

Interactive API Docs / POST body data omitted using consumes 'application/x-www-form-urlencoded'

Steps to duplicate:

 

Take for example this api which defines a method capable of consuming application/x-www-form-urlencoded and text/plain:

https://swaggerhub.com/api/evosus/webapi/1.3.0

POST /method/Inventory_Item_StockSiteQuantity_Get

 

Enter the 3 required fields as follows:

CompanySN: 20091102165026*177

ticket: d5fef8e5-a3d3-456e-b4a9-5203c947ee97

body: blah blah blah

 

With parameter content-type set to application/x-www-form-urlencoded and click 'Try this out'. Notice the -d parameter in the curl command is missing.

curl -X POST --header "Content-Type: application/x-www-form-urlencoded" --header "Accept: application/json" "https://cloud3.evosus.com/api/method/Inventory_Item_StockSiteQuantity_Get?ticket=d5fef8e5-a3d3-456e-b4a9-5203c947ee97&CompanySN=20091102165026*177"

 

With parameter content-type set to text/plain click 'Try this out'. Notice the -d parameter is set properly.

curl -X POST --header "Content-Type: text/plain" --header "Accept: application/json" -d "blah blah blah" "https://cloud3.evosus.com/api/method/Inventory_Item_StockSiteQuantity_Get?ticket=d5fef8e5-a3d3-456e-b4a9-5203c947ee97&CompanySN=20091102165026*177"

 

Is there something I am doing wrong? Thanks in advance for your assistance. 

 

1 ACCEPTED SOLUTION

Accepted Solutions
Occasional Contributor

Re: Interactive API Docs / POST body data omitted using consumes 'application/x-www-form-urlencoded'

I got to the bottom of the problem. I can't argue with your observation that I don't have CORS enabled since it was throwing the CORS error. Specifically an error during the preflight request. Preflight is the key word.

 

A pre-flight request is only associated with a complex CORS request and not a simple CORS request. My request WAS simple when my content-type was x-www-form-urlencoded. When I changed my request to content-type application/json the CORS requirement, by definition, changed to COMPLEX. This is explained in the excellent HTMLRocks CORS topic (http://www.html5rocks.com/en/tutorials/cors/).

 

I had the CORS headers, as shown above on my POST request. However, the preflight request uses the OPTIONS verb. My web service did not handle the OPTIONS verb. Now it does. Now it works.

 

Most web service implementations will probably find it easiest to implement the handling of OPTIONS calls using a request filter. Check for the OPTIONS verb and short-circuit the request with a null response prior to route handling. Alternately you can implement an OPTIONS verb in the route handler in addition to your other http verbs. The calling web site only needs to see the proper headers in the response.

  

Thanks for your support.

6 REPLIES 6
Moderator

Re: Interactive API Docs / POST body data omitted using consumes 'application/x-www-form-urlencoded'

Hi there,

 

The problem lies within the Swagger spec you have. Body parameters can't really be used with application/x-www-form-urlencoded and vice versa. If you need to use application/x-www-form-urlencoded, then you have to define the parameter(s) as formData (but then you will not be able to specify models). If you do you want to have a body payload for an operation, then the mime type would represent the data type to be sent. For example, if you expect to get a JSON, the mime type would be application/json.

Occasional Contributor

Re: Interactive API Docs / POST body data omitted using consumes 'application/x-www-form-urlencoded'

+1 for getting model working for formData.

 

What I am trying to express is one or the other of these HTTP requests (these work directly in Fiddler):

 

GET http://cloud3.evosus.com/api/method/Inventory_Item_StockSiteQuantity_Get?args={"ItemCode":"23154BIO"... HTTP/1.1

Accept: application/json
Host: cloud3.evosus.com

-----

 

POST http://cloud3.evosus.com/api/method/Inventory_Item_StockSiteQuantity_Get?ticket=d5fef8e5-a3d3-456e-b... HTTP/1.1

Accept: application/json
Content-Type: application/x-www-form-urlencoded
Host: cloud3.evosus.com

 

args={"ItemCode":"23154BIO"}

-----

 

You can see that I am expressing the model as JSON in the value of the args parameter. In the case of the POST, the body is application/x-www-form-urlencoded. I can express a model of any type using this technique.

 

I am finding it very difficult to express what is needed for my server API. I already know that the Interactive API Docs UI will not produce the needed request without some manual editing of the parameters. However, had the use of a body parameter allowed Content-Type: application/x-www-form-urlencoded to be used I could have instructed the user to click the Model Schema to populate the template of the body and then prepend the body with 'args='. But this is not possible.

 

My current workaround is to create an 'args' query parameter of type string, and an optional body parameter referencing my model. I accompany this with instructions to click the Model Schema box and cut the contents of the body into the args query parameter. Very hacky but it works. It would be slightly better if instead of an 'args' query parameter I could use a formData parameter. But I cannot have a body and a formData parameter together. The UI is blocking me at every turn. 

 

Can I do better some other way?

Moderator

Re: Interactive API Docs / POST body data omitted using consumes 'application/x-www-form-urlencoded'

This is my personal opinion - we're not going to support that kind of structure, not for query parameters and not for form parameters (of that structure). The only way to pass a model is if you define how it's being represented and when it comes to HTTP, the way to do is is to define the mime type of the content which affects the *payload* only. To me, it just doesn't make sense.

 

If you have only one parameter, I don't really understand why you don't define it as application/json and just send it as a payload (the "args" name doesn't add anything).

 

However, putting all that aside, there's really no way to describe what you want with 2.0. This is not a SwaggerHub issue but rather a spec restriction that cannot change within SwaggerHub.

Highlighted
Occasional Contributor

Re: Interactive API Docs / POST body data omitted using consumes 'application/x-www-form-urlencoded'

Thank you! I took your advice a changed the server API to consume application/json. Unfortunately I'm still having some difficulty getting SwaggerHub to create a valid request.

  

As a case in point see:

https://swaggerhub.com/api/evosus/webapi/1.4.0

POST /method/Inventory_Item_Get

 

Enter the value 23112BIO for the ItemCode. Accept the defaults for the other parameters.

 

The equivalent CURL request which was copied from the Interactive API Docs page is here. If I execute this from a terminal I get good results.

 

curl -X POST --header "Content-Type: application/json" --header "Accept: application/json" -d "{
  \"args\": {
    \"ItemCode\": \"23112BIO\"
  }
}" "https://cloud3.evosus.com/api/method/Inventory_Item_Get?CompanySN=20091102165026*177&ticket=d5fef8e5-a3d3-456e-b4a9-5203c947ee97"

 

But the Try this out! button on Interactive API Docs which produced the above CURL command does not produce results. It gives response code 0. See the screenshot link here. The Send Request button from the Editor tab gives the same result.

  

The equivalent request in Fiddler produces proper results:

  

POST http://cloud3.evosus.com/api/method/Inventory_Item_Get?ticket=d5fef8e5-a3d3-456e-b4a9-5203c947ee97&CompanySN=20091102165026*177 HTTP/1.1
Accept: application/json
Content-Type: application/json
Host: cloud3.evosus.com

{ "args": { "ItemCode": "23112BIO"}}

 

I appreciate any guidance you can give me. I would really love to be able to create a valid request using your tools.

 

Edited 12/14 5:30PM

My browser is reporting a CORS issue:

Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://swaggerhub.com' is therefore not allowed access. The response had HTTP status code 405.

You can see the CORS header values from my (valid) Fiddler request response here (if that helps):

HTTP/1.1 200 OK
Cache-Control: private
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/8.5
X-Powered-By: ServiceStack/3.971 Win32NT/.NET
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept

 

- Steve

Moderator

Re: Interactive API Docs / POST body data omitted using consumes 'application/x-www-form-urlencoded'

That's actually because you don't have CORS enabled in your server - https://github.com/swagger-api/swagger-ui#cors-support

 

Fiddler, being a non-browser tool, does not require CORS, but browsers unfortunately require that.

Occasional Contributor

Re: Interactive API Docs / POST body data omitted using consumes 'application/x-www-form-urlencoded'

I got to the bottom of the problem. I can't argue with your observation that I don't have CORS enabled since it was throwing the CORS error. Specifically an error during the preflight request. Preflight is the key word.

 

A pre-flight request is only associated with a complex CORS request and not a simple CORS request. My request WAS simple when my content-type was x-www-form-urlencoded. When I changed my request to content-type application/json the CORS requirement, by definition, changed to COMPLEX. This is explained in the excellent HTMLRocks CORS topic (http://www.html5rocks.com/en/tutorials/cors/).

 

I had the CORS headers, as shown above on my POST request. However, the preflight request uses the OPTIONS verb. My web service did not handle the OPTIONS verb. Now it does. Now it works.

 

Most web service implementations will probably find it easiest to implement the handling of OPTIONS calls using a request filter. Check for the OPTIONS verb and short-circuit the request with a null response prior to route handling. Alternately you can implement an OPTIONS verb in the route handler in addition to your other http verbs. The calling web site only needs to see the proper headers in the response.

  

Thanks for your support.

New Here?
Join us and watch the welcome video:
Watch the New Interview
7Mistakes
Join the September Hub-bub to show off, learn and win