Parameter Binding in ASP.NET Web API
In the previous section, we learned how Web API route an HTTP request to a controller and action method. Here, we will learn how Web API binds HTTP request data to the parameters of an action method.
Action methods in Web API controllers can have one or more parameters of different types. It can be either primitive type or complex type. Web API binds action method parameters with the URL's query string or with the request body depending on the parameter type.
By default, if the parameter type is of .NET primitive types such as int, bool, double, string, GUID, DateTime, decimal, or any other type that can be converted from string type, then it sets the value of a parameter from the query string. And if the parameter type is the complex type, then Web API tries to get the value from the request body by default.
The following table lists the default rules for parameter binding.
HTTP Method | Query String | Request Body |
---|---|---|
GET | Primitive Type, Complex Type | NA |
POST | Primitive Type | Complex Type |
PUT | Primitive Type | Complex Type |
PATCH | Primitive Type | Complex Type |
DELETE | Primitive Type, Complex Type | NA |
Let's see how Web API get values of action method parameters from the HTTP request.
Get Action Method with Primitive Parameter
Consider the following example of the GET
action method that includes a single primitive type parameter.
public class StudentController : ApiController
{
public Student Get(int id)
{
}
}
As you can see, the above HTTP GET
action method includes the id
parameter of the int
type. So, Web API will try to extract the value of id from the query string of the requested URL, convert it into int and assign it to the id
parameter of the GET
action method. For example, if an HTTP request is http://localhost/api/student?id=1
then the value of the id
parameter will be 1.
The followings are valid HTTP GET
Requests for the above action method.
http://localhost/api/student?id=1
http://localhost/api/student?ID=1
Query string parameter name and action method parameter name must be the same (case-insensitive). If names do not match, then the values of the parameters will not be set. The order of the parameters can be different.
Multiple Primitive Parameters
Consider the following example of the GET
action method with multiple primitive parameters.
public class StudentController : ApiController
{
public Student Get(int id, string name)
{
}
}
As you can see above, an HTTP GET
method includes multiple primitive type parameters. So, Web API will try to extract the values from the query string of the requested URL. For example, if an HTTP request is http://localhost/api/student?id=1&name=steve
, then the value of the id
parameter will be 1, and the name
parameter will be "steve"
.
Followings are valid HTTP GET Requests for the above action method.
http://localhost/api/student?id=1&name=steve
http://localhost/api/student?ID=1&NAME=steve
http://localhost/api/student?name=steve&id=1
Query string parameter names must match with the name of an action method parameter. However, they can be in a different order.
POST Action Method with Primitive Parameter
An HTTP POST
request is used to create a new resource. It can include request data into the HTTP request body and also in the query string.
Consider the following Post action method.
public class StudentController : ApiController
{
public Student Post(id id, string name)
{
}
}
As you can see above, the Post()
action method includes primitive type parameters id and name. So, by default, Web API will get values from the query string. For example, if an HTTP POST request is http://localhost/api/student?id=1&name=steve
, then the value of the id
parameter will be 1 and the name
parameter will be "steve"
in the above Post()
method.
Now, consider the following Post()
method with the complex type parameter.
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
}
public class StudentController : ApiController
{
public Student Post(Student stud)
{
}
}
The above Post()
method includes the Student
type parameter. So, as a default rule, Web API will try to get the values of the stud
parameter from the HTTP request body.
Following is a valid HTTP POST request in the fiddler for the above action method.
Web API will extract the JSON object from the HTTP request body above, and convert it into a Student
object automatically because the names of JSON object's properties match with the name of the Student
class properties (case-insensitive).
POST Method with Mixed Parameters
The HTTP Post
action methods can include primitive and complex type parameters. Consider the following example.
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
}
public class StudentController : ApiController
{
public Student Post(int age, Student student)
{
}
}
The above Post method includes both primitive and complex type parameters. So, by default , Web API will get the age
parameter from query string and student
parameter from the request body.
Following is a valid HTTP POST request in the fiddler for the above action method.
Post action method cannot include multiple complex type parameters because, at most, one parameter is allowed to be read from the request body.
Parameter binding for Put and Patch method will be the same as the POST
method in Web API.
[FromUri] and [FromBody]
You have seen that by default, ASP.NET Web API gets the value of a primitive parameter from the query string and a complex type parameter from the request body. But, what if we want to change this default behavior?
Use [FromUri]
attribute to force Web API to get the value of complex type from the query string and [FromBody]
attribute to get the value of primitive type from the request body, opposite to the default rules.
For example, consider the following GET
method.
public class StudentController : ApiController
{
public Student Get([FromUri] Student stud)
{
}
}
In the above example, the Get()
method includes a complex type parameter with the [FromUri]
attribute. So, Web API will try to get the value of the Student
type parameter from the query string. For example, if an HTTP GET request http://localhost:xxxx/api/student?id=1&name=steve
then Web API will create an object the Student
type and set its id
and name
property values to the value of id
and name
query string parameter.
The name of the complex type's properties and the query string parameters must match.
In the same way, consider the following example of Post()
method.
public class StudentController : ApiController
{
public Student Post([FromUri]Student stud)
{
}
}
As you can see above, we have applied the [FromUri]
attribute with the Student
parameter. By default, Web API extracts the value of the complex type from the request body, but here, we have applied the [FromUri]
attribute. So now, Web API will extract the value of the Student
properties from the query string instead of the request body.
In the same way, apply the [FromBody]
attribute to get the value of primitive data type from the request body instead of a query string, as shown below.
public class StudentController : ApiController
{
public Student Post([FromBody]string name)
{
}
}
Following is a valid HTTP POST request in the fiddler for the above action method.
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.
The following figure summarizes parameter binding rules.