Model Binding In ASP.NET MVC Core

Introduction

Model binding in MVC maps HTTP request data to the parameters of the controller's action method. The parameter may either be of simple type like integers, strings, double etc. or complex types.

When we look into the request life cycle of MVC, the request is first received by the routing and from the URL, MVC identifies the Controller and action method, using routing. Routing binds the values from HTTP request to action's parameter, using model binder.

MVC binds the request data to the action parameter by parameter name. MVC will bind the action parameter from the various parts of the request. Following are the data sources in the order, which model binding looks through.

  1. Form values - These are the form data, which go with HTTP request, using POST method.
  2. Route values - The set of route values provided by MVC routing.
  3. Query strings - The query string data, part of the URL.

All the values from Form values, route data, and query strings are stored as the name-value pairs. The Model binding starts looking from "Form values" and it finds the parameter values by the parameter name. First, model binding looks into the form values. If it does not find any matching value, it moves on the route value for that parameter name. If it finds the matching binding, Model binding looks for other parameter.

For example, consider the URL, given below-

http://theexample.com/example/edit/2

The code for the action method looks, as given below-

  1. [Route("home/edit/{id?}")]  
  2. public IActionResult Edit(int? id)  
  3. {  
  4. }  
The model binding looks for a key "id". When key "id" is found from the name-values pair, binding happens and the value is converted to an integer.

In the example, shown above we have talk about the simple type. If the action has parameter with non-primitive type such as class which may contains both types of properties: simple and complex, MVC model binding is able to handle the things. MVC model binding looks for the pattern "parametername.propertyname" to bind the values. If model binding doesn’t find any matching for the said pattern, it looks for using property name. For the collection type, it looks for the parameter_name[index] or only [index] and treats as a Dictionary types.

For the complex type parameter, class must have a public default constructor and properties used for binding must have public settable properties. Model binding uses only public default constructor for class initialization.

Model binding uses reflection and recursion to traverse the properties of the complex types for the property matches. Once Model binding binds any value with the property, it stops looking for the value with that name and move on the next parameter. MVC doesn’t throw any error, when binding fails.

Handle the behavior of Model binding using attribute

There are many attributes contained by MVC, which help us control the behavior of the Model binding. For example, “BindNever” attribute is used to tell Model binding, which does not bind any value to this parameter.

Following is the list of attributes supported by the Model binding-  
  • BindNever
    This attribute tells to the Model binder to not to bind the value with the parameter.

  • BindRequired
    This attribute tells the Model binder that binding is required. If binding is not found, this attribute adds the error to the model state.

  • FromHeader
    This attributes defines the binding source that is request header.

  • FromQuery
    This attribute tells to Model binder to search the binding value from the query string.

  • FromRoute
    This attribute tells to Model binder to search the binding value from the route.

  • FromForm
    This attribute tells to Model binder to search the binding value from the form.

  • FromServices
    This attribute uses DI (Dependency Injection) to bind the parameters from the Services.

  • FromBody
    This attribute tells to Model binder to search the binding value from request body. It uses configured formatter to bind the value from the body and formatter is defined in the content type of the request.

  • ModelBinder
    This tells to Model binding, which uses custom model binder to bind the parameters.

Binding the data from request body

Request data can be formatted in JSON, XML and many other formats. If we use FromBody attribute, MVC understands that the data comes from the request body and the format of the data in the body, which is defined in the request content type. Default format for MVC is JSON (JsonInputFormatter) but we can add additional formatters.

We are able to configure the data format in Startup.cs file. In following example, I have configured XML formatter. ConfigureServices method of the Startup.cs file contains Services as an argument; we can configure the service as need basis. In our example, XML formatter is added to the Service, using "AddMvc" method. The "AddMvc" method helps us to configure the filters, formatters and other system options from MVC.

  1. public void ConfigureServices(IServiceCollection services)  
  2. {  
  3.    services.AddMvc().AddXmlSerializerFormatters();  
  4. }  
Example

In the example, shown below, I have used a query string as a binding source. I am sending the Id value in URL, using the query string. Here, I have created simple GET request, so I can test this, using my Browser. To create an example, I am using VS Code editor.

Controller Code
  1. [Route("home/edit/{id?}")]  
  2. public IActionResult Edit(int? id)  
  3. {  
  4.    return Ok(id);  
  5. }  
Debug Window

Debug window

I have created another example in which I am using the form value as a source. In this example, I am posting some data in to the controller. Here, I have not created any view and I am using Fiddler to post the data to the controller.

Controller Code
  1. [Route("home/post")]  
  2. [HttpPost]  
  3. public IActionResult Post([FromBody] User user)  
  4. {  
  5.    return Ok(true);  
  6. }  
As we seen here, I have decorated “Post” method with “HttpPost” attribute. The “FromBody” attribute tells Model binder to search the binding value from the request body.

Debug window

Conclusion - Model binding is a very important feature in MVC. It helps us to bind the client data to method parameter. MVC provides various attributes which help us to handle the behavior of the model binding.