Before diving in-depth of Model Binding in Web API 2, I would highly
recommend you to go ahead and check “Content Negotiation in Web API 2”.
The article will give you glimpse over creating Web API projects and how
to use POSTMAN for testing your web APIs. For this article, I will
consider the same project I created in Content Negotiation and Postman
for testing. The mechanism to map the service request and its input data
to the correct action method and its parameters is known as Model
Binding aka Parameter Binding.
So now, a very genuine question some of you must be thinking “How
does the model binder understands, which method to be linked to with the
requested URI?” Hmmmm…. A good question!! Let’s see how this is
managed.
Similarly, when an Action Method is suffixed with HTTP Verb, GET PUT
POST DELETE, along with input parameter (non-mandatory) is mapped to the
URL
Let us consider the GET method. I requested the URL ‘api/Products’.
Ok so now, the model binder first checks if the URL is decorated as
required – “Ummm… Yes!! It has an API followed by Controller name. But
no ID, ok!! That’s fine. It was anyways optional. I accept the URL. But
wait, let me check if there is an input parameter in the request body?
No. ok! So there is no input parameter anywhere so this seems to be the
GET method. Let me now check in the action method list if I can find any
method prefixed with GET and not accepting any input parameter. There
it is, the GETPRODUCTS method”. In return, we get back the list of
products.
Similarly, it works for other Action methods. But wait, this means I
have to always prefix my method name with HTTP Verb? Won’t I be able to
ever have a custom name? Let’s see what happens. I changed the
GETPRODUCTS to LOADPRODUCTS and called the ‘api/Products’.
We land up getting an error.
So what now? Each HTTP verb is connected to HTTP Method.
So you simple need to decorate your method with the HTTP Method and rename your method as you desire.
Call the method in Postman and you get the product list back
Similarly, you can decorate your action methods with the desired HTTP Method and get the result.
In above image, ‘int id’ is the primitive type which accepts data
from the URL or Query String whereas ‘Product product’ is complex type
which accepts data from Request Body.
So we can decorate ‘int id’ with [FromUri] and ‘Product product’ as
[FromBody]. In both the cases, calling the method and passing parameter
would be same, the default behavior. Please Note: For the complex
type, you need to pass all the properties mentioned in its entity class
in the request body irrespective of ‘int id’ parameter. Now, what if I
want to accept the primitive type from the body whereas the complex type
from the URI? This can be achieved by decoration our method as follows,
In this case, we need to pass the ‘Id’ parameter through Request Body whereas the ‘Product’ as Query String or Route data.
Let’s see if our action method gets the value when we sent the request.
Ooo yes!! Our action method was successful to receive the input.
Similarly, you can choose which input value you want the web API to read
from as per your application needs. Also, you can decorate [FromUri]
and [FromBody] in other HTTP methods, as per requirement.
HOW DOES WEB API BIND THE HTTP VERBS TO THE ACTION METHOD
This is taken care by the WebAPIConfig and HTTP Verbs. The Route config for WebApi tells us the URL parameter it should accept. Observe the RouteTemplate parameter in the below figure. It says that any URL which is decorated with API followed by the controller name, in our case its Products, and also having a facility to provide Id, not mandatory, is a correct URL.
HTTP VERB
HTTP METHOD
Get
HttpGet
Post
HttpPost
Put
HttpPut
Delete
HttpDelete
TYPES OF MODEL BINDER
Model Binders are precisely of two types,- Primitive model binder
- Complex model binder
Primitive Model Binder
- If the request is simple, i.e. input parameter are of type int,
string, Boolean, GUID, decimal, etc. & is available in the URL, then
such kind of request is mapped to primitive model binding.
- Data is available as Query String
Complex Model Binder
- If the request is complex, i.e. we pass data in request body as
an entity with the desired content-type, then such kind of request is
mapped by Complex model binder.
- Data not available via Query String
DEFAULT MODEL BINDERS
Till now you must have understood what methods use primitive type binding and which methods use complex type binding. I would just note it down though.Primitive Type Binding
HTTP Methods like GET and DELETE where you are only required to send less quantity of input parameters, uses primitive type binding, by default.Complex Type Binding
- HTTP Methods like POST and PUT where you have to send the send
model/entity data to the server, uses complex type binding, by default.
- POST and PUT can also use combination of primitive and
complex type. Consider you want to update data. So you can pass the Id
in query string and the data to be updated in response body.