Reputation:
I'm having trouble POSTing to my WEBAPI.
My code for my ASP.NET WEBAPI is as follows:
[RoutePrefix("api/Test")]
public class TestController : ApiController
{
// GET: api/Test
[Route]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
[Route]
public void Post([FromBody]string value)
{
Debugger.Break();
}
The calls from my Vue.js app via axios are as follows:
PostTest(){
alert("Post Test Starting");
var data = new FormData();
data.set('value','test');
//var data = {'value': 'test'};
this.CallAxios('post', 'http://localhost:10000/api/Test/', data, axiosHeaders);
},
CallAxios(callMethod, callURL, callData, callHeaders)
{
axios({
method: callMethod,
url: callURL,
data: callData,
headers: callHeaders
}).then((response) => {
alert(response.data)
})
}
My Content-Type for all requests is set to application/json
If I call the PostTest Vue method using the FormData section and leaving the [FromBody] attribute on the .NET API Post method I receive the following 415 "Unsupported Media Type" error:
{"Message":"The request entity's media type 'multipart/form-data' is not supported for this resource.","ExceptionMessage":"No MediaTypeFormatter is available to read an object of type 'String' from content with media type 'multipart/form-data'.",
So even though I specified application/json for the Content-Type it is still coming across as multipart/form-data
If I switch the Vue.js code to use the "var data = {'value': 'test'}" and I remove the [FromBody] attribute from the .NET Post parameter I receive the following 405 "Method Not Allowed" error:
{"Message":"The requested resource does not support http method 'POST'."}
I've been fighting with this for a while. It seems I can do one of the following options:
Upvotes: 0
Views: 2481
Reputation: 630
There's two ways to accomplish this (neither of them will use FormData)
1) Sending as Content-Type: application/x-www-form-urlencoded . To do this you'll need to URL-encode the parameter with a library like qs. However, notice this special WebAPI caveat (empty key name)
import qs from 'qs';
let myValue = 'FontSpace'
let options = {
url: '/api/fonts'
, method: 'post'
, data: qs.stringify({ '': myValue })
}
let response = await this.$http(options)
If you inspect the request in devtools you'll see the parameter gets encoded as
=FontSpace
2) Sending as Content-Type application/json . To do this you'll JSON.stringify JUST the value (no key) and also explicitly specify the content-type in the headers
let myValue = 'FontSpace'
let options = {
headers: { 'Content-Type': 'application/json' }
, url: '/api/fonts'
, method: 'post'
, data: JSON.stringify(myValue)
}
let response = await axios(options)
Inspect in devtools and you'll see the the parameter gets JSON encoded
"FontSpace"
As long as your encoding and your content-type matches, WebAPI2 will accept your request.
This documentation was helpful
When a parameter has [FromBody], Web API uses the Content-Type header to select a formatter. In this example, the content type is "application/json" and the request body is a raw JSON string (not a JSON object).
Upvotes: 1