Tuesday, 25 July 2017

Web APi Parameter Binding

Here, we will learn how Web API binds HTTP request data to the parameters of an action method.
Action methods in Web API controller can have one or more parameters of different types. It can be either primitive type or complex type. Web API binds action method parameters either with URL's query string or with request body depending on the parameter type. By default, if parameter type is of .NET primitive type 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 complex type then Web API tries to get the value from request body by default.
The following table lists the default rules for parameter binding.
HTTP MethodQuery StringRequest Body
GETPrimitive Type, 
Complex Type
NA
POSTPrimitive TypeComplex Type
PUTPrimitive TypeComplex Type
PATCHPrimitive TypeComplex Type
DELETEPrimitive Type,
Complex Type
NA
Let's see how Web API get values of action method parameters from HTTP request.

Get Action Method with Primitive Parameter:

Consider the following example of Get action method that includes single primitive type parameter.
Example: Primitive Parameter Binding

public class StudentController : ApiController
{
    public Student Get(int id) 
    {
              
    }
}

As you can see above Get action method includes id parameter of int type. So, Web API will try to extract the value of id from the query string of requested URL, convert it into int and assign it to id parameter of Get action method. For example, if an HTTP request is http://localhost/api/student?id=1 then value of id parameter will be 1.
Followings are valid HTTP GET Requests for the above action method.
http://localhost/api/student?id=1
http://localhost/api/student?ID=1
Note:Query string parameter name and action method parameter name must be the same (case-insensitive). If names do not match then values of the parameters will not be set. The order of the parameters can be different.

Multiple Primitive Parameters:

Consider the following example of Get action method with multiple primitive parameters.
Example: Multiple Parameters Binding

public class StudentController : ApiController
{
    public Student Get(int id, string name) 
    {

    }
}

As you can see above, Get method includes multiple primitive type parameters. So, Web API will try to extract the values from the query string of request URL. For example, if an HTTP request is http://localhost/api/student?id=1&name=steve then value of id parameter will be 1 and name 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
Note:Query string parameter names must match with the name of an action method parameter. However, they can be in different order.

POST Action Method with Primitive Parameter:

HTTP POST request is used to create new resource. It can include request data into HTTP request body and also in query string.
Consider the following Post action method.
Example: Post Method with Primitive Parameter

public class StudentController : ApiController
{
    public Student Post(id id, string name)
    {
           
    }
}

As you can see above, 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 id will be 1 and name will be "steve" in the above Post() method.
Now, consider the following Post() method with complex type parameter.
Example: Post Method with 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 Student type parameter. So, as a default rule, Web API will try to get the values of stud parameter from HTTP request body.
Following is a valid HTTP POST request in the fiddler for the above action method.
Parameter Binding
Web API will extract the JSON object from the Request body above and convert it into Student object automatically because names of JSON object properties matches with the name of Student class properties (case-insensitive).

POST Method with Mixed Parameters:

Post action method can include primitive and complex type parameters. Consider the following example.
Example: Post Method with Primitive and Complex Type Parameters

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 parameter. So, by default , Web API will get the id 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.
Parameter Binding
Note: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 Post method in Web API.

[FromUri] and [FromBody]:

You have seen that by default Web API gets the value of a primitive parameter from the query string and complex type parameter from the request body. But, what if we want to change this default behaviour?
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.
Example: FormUri

public class StudentController : ApiController
{
    public Student Get([FromUri] Student stud)
    {

    }
}

In the above example, Get method includes complex type parameter with [FromUri] attribute. So, Web API will try to get the value of 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 Student object and set its id and name property values to the value of id and name query string.
Note:Name of the complex type properties and query string parameters must match.
The same way, consider the following example of Post method.
Example: FromUri

public class StudentController : ApiController
{
    public Student Post([FromUri]Student stud)
    {

    }
}

As you can see above, we have applied [FromUri] attribute with the Student parameter. Web API by default extracts the value of complex type from request body but here we have applied [FromUri] attribute. So now, Web API will extract the value of Student properties from the query string instead of request body.
The same way, apply [FromBody] attribute to get the value of primitive data type from the request body instead of query string, as shown below.
Example: FromBody

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.
Parameter Binding
Note:FromBody attribute can be applied on only one primitive parameter of an action method. It cannot be applied on multiple primitive parameters of the same action method.
The following figure summarizes parameter binding rules.

Web API Routing

No comments:

Post a Comment