I have this controller action :
[HttpPost]
[ActionName("aaa")]
public HttpResponseMessage aaa(Z z) //notice - no [FromBody]
{
return Request.CreateResponse(HttpStatusCode.OK, 1);
}
Where Z
is :
public class Z
{
public string a { get; set; }
}
But when I post via fiddler :
POST http://localhost:11485/api/profiles/aaa HTTP/1.1
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Host: localhost:11485
Content-Length: 3
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8,he;q=0.6
Cache-Control: no-cache
Connection: keep-alive
a=1
I can actually see it is working :
Question:
If so , how does it working without the [FromBody] attribute ? and do I still need /not write this attribute ?
Also , what is the scenario where not writing this attribute - will cause problems ?
Using [FromBody] 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).
The [FromBody] attribute can be applied on only one primitive parameter of an action method. It cannot be applied to multiple primitive parameters of the same action method.
[FromQuery] - Gets values from the query string. [FromRoute] - Gets values from route data. [FromForm] - Gets values from posted form fields. [FromBody] - Gets values from the request body.
Binding is different for MVC and Web API. By default, ASP.NET Web API binds complex types from the request message body and simple types from URI, query string, etc. Since you specified Z
, which is a class (complex type), it populates the action method parameter from body without you having to specify [FromBody]
. On the other hand, if your request is http://localhost:11485/api/profiles/aaa?z=1
without a body, it will NOT bind to your complex parameter automatically. In that case, you will need to specify [FromUri]
like this: public HttpResponseMessage aaa([FromUri]Z z)
.
On the other hand, say your action method is public HttpResponseMessage aaa(string a)
. We now have string
, which is a simple type. In this case, http://localhost:11485/api/profiles/aaa?a=1
without a message body will let Web API bind the parameter correctly without you having to specify [FromUri]
. Now, if you want to bind from body in this case, you will need to specify public HttpResponseMessage aaa([FromBody]string a)
. Of course, for this body must be =1
, for application/x-www-form-urlencoded
, without the key name of a
.
Bottom line - your parameter (simple type or complex type) determines how Web API binds. To make it work differently from the default behavior, you need to tell via FromUri
or FromBody
.
PS. Whatever I mentioned above holds good purely for the good old ASP.NET Web API (including 2). In ASP.NET 5.0 a.k.a ASP.NET vNext or ASP.NET MVC 6.0, MVC and Web API have been unified. In order for it to bind a complex type from body, you must specify [FromBody]
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With