ASP.NET MVC : Model Binding

Model binding in MVC maps data from HTTP requests to action method parameters. The parameters may be simple types such as strings, integers, or floats, or they may be complex types. This is a great feature of MVC because mapping incoming data to a counterpart is an often repeated scenario, regardless of size or complexity of the data. MVC solves this problem by abstracting binding away so developers don’t have to keep rewriting a slightly different version of that same code in every app. Writing your own text to type converter code is tedious, and error prone.

How model binding works

When MVC receives an HTTP request, it routes it to a specific action method of a controller. It determines which action method to run based on what is in the route data, then it binds values from the HTTP request to that action method’s parameters. For example, consider the following URL:

http://contoso.com/movies/edit/2

Since the route template looks like this, {controller=Home}/{action=Index}/{id?}, movies/edit/2
routes to the Movies controller, and its Edit action method. It also accepts an optional parameter called id. The code for the action method should look something like this:

public IActionResult Edit(int? id)

MVC will try to bind request data to the action parameters by name. MVC will look for values for each parameter using the parameter name and the names of its public settable properties. In the above example, the only action parameter is named id, which MVC binds to the value with the same name in the route values. In addition to route values MVC will bind data from various parts of the request and it does so in a set order. Below is a list of the data
sources in the order that model binding looks through them:

  1. Form values: These are form values that go in the HTTP request using the POST method. (including jQuery POST requests).
  2. Route values: The set of route values provided by routing. 
  3.  Query strings: The query string part of the URI.

Since model binding asked for a key named id and there is nothing named id in the form values, it moved on to the route values looking for that key. In our example, it’s a match. Binding happens, and the value is converted to the integer 2. The same request using Edit (string id) would convert to the string “2”.  So far the example uses simple types. In MVC simple types are any .NET primitive type or type with a string type converter. If the action method’s parameter were a class such as the Movie type, which contains both simple and complex
types as properties, MVC’s model binding will still handle it nicely. It uses reflection and recursion to traverse the properties of complex types looking for matches. Model binding looks for the pattern parameter_name.property_name to bind values to properties. If it doesn’t find matching values of this form, it will attempt to bind using just the property name.

For those types such as Collection types, model binding looks for matches to parameter_name[index] or just [index]. Model binding treats Dictionary types similarly, asking for parameter_name[key] or just [key], as long as they keys are simple types. Keys that are supported match the field names HTML and tag helpers generated
for the same model type. This enables round-tripping values so that the form fields remain filled with the user’s input for their convenience, for example, when bound data from a create or edit did not pass validation.
In order for binding to happen, members of classes must be public, writable properties containing a default public constructor. Public fields are not bound. Properties of type IEnumerable or array must be settable and will be populated with an array. Collection properties of type ICollection<T> can be read-only.

Leave a Reply

Your email address will not be published. Required fields are marked *