If you are using jQuery’s ajax function to post raw JSON string to your APIs, you might get some problem when your API does not receive the correct content, or in the case of ASP.NET Web API and parameter binding, you may get null input parameters in your controller.
The JavaScript can be as simple as this.
1 2 3 4 5 6 |
$.ajax('/api/test', { type: 'post', data: 'inputparameter', dataType: 'json', success: function(data) { alert('Receive: ' + data); } }); |
And the post action of the Test API controller be something like below.
1 2 3 4 |
public string Post([FromBody]string input) { return input; } |
The post action will not get “inputparameter” as the value of variable input; instead we get a null value.
Looking at the HTTP request, you will see the body as
1 |
inputparameter: |
Ha, so apparently there are 2 issues here:
- The parameter is not wrapped in double quote as required in JSON string.
- A strange colon appears at the end.
I thought that jQuery somehow preprocess my parameters, so I set processData to false.
1 2 3 4 5 6 7 |
$.ajax('/api/test', { type: 'post', data: 'inputparameter', dataType: 'json', processData: false, success: function(data) { alert('Receive: ' + data); } }); |
However, the above code would not work either. The HTTP request’s content is the same as before.
A deeper look into the HTTP request’s header shows a more interesting information: the Content-Type is “application/x-www-form-urlencoded; charset=UTF-8”. So that means the ajax call takes ‘application/x-www-form-urlencoded’ as default and format my data accordingly.
Having known all the causes of my issues, it is not so difficult to come up with a solution:
- Use JSON.stringify() to properly format JSON string
- Add settings contentType: ‘application/json’ to the ajax call
Here is the final code.
1 2 3 4 5 6 7 |
$.ajax('/api/test', { type: 'post', data: JSON.stringify('inputparameter'), dataType: 'json', contentType: 'application/json', success: function(data) { alert('Receive: ' + data); } }); |
I hope this blog post will save you some time if you get the same problem. Please comment below if you have any better solution.