Model binding is a technique that allows you to map data to your controller actions in ASP.NET MVC. In the old days one would manually call
Request["param"] to get the value of а parameter, but this could quickly become annoying as you get many parameters (f.x., via form POST). Model binding abstracts away this tedious activity and allows us to focus on designing our controllers. The process itself looks like this:
A nice bonus is that we can map our models from any kind of request, for example a form POST or AJAX.
Model binding in ASP.NET MVC
Model binding is an essential concept of ASP.NET MVC, but yet people do not use it often. I guess this is due to the fact that many developers have been working with pure ASP.NET for long time where you usually access the query string via
Request. In MVC you should simply add an argument to the action method in your controller.
The model binding mechanism relies on the
DefaultModelBinder class, which is responsible for resolving the request type (is it JSON, XML or form POST), parsing it (with the help of value providers) and mapping it to the requested model.
When to use model binding
I use model binding for all requests to the controllers. Be it a GET or POST request, you can use model binding. This makes your controllers clear and focused on their presentation logic. A few examples when you can use this mechanism:
- Bind POST parameters to a model
- Bind query string to simple objects, for example, you can bind the search term to a string
- You have a query string parameter which is a serialized value of a complex object. Here you have two options: either bind it to a string argument and then manually deserialize it or, better in my opinion, create a custom model binder that does the deserialization for you and binds it directly to the custom model
You can actually use model binding for non-request mappings, for example when accessing value from the session. I use custom models to abstract away the session, current user, request URL, etc. This makes my controllers clear and simple. I try to avoid accessing directly the
Session or any other properties that each controller in ASP.NET MVC has (because it inherits from
Controller), because this makes my controller tightly-coupled and harder to test afterwards. Moreover, it makes my presentation logic simple and easy to follow by removing any dependencies on other properties. The controller uses only what it is supposed to use – either injected via the constructor or as an argument to the action method.
Implementing your own model binder
Although the built-in model binding mechanism will serve you fine in most cases, you may still want to implement custom logic for your application. You can easily achieve this by implementing
IModelBinder interface and register the model binder afterwards. This can happen in two ways:
- Decorate your model properties (or the entire argument of the action method) with
ModelBinderAttributeand provide your model binder type as an argument to the attribute. This should be done every time you need the model binder.
- Register it via
ModelBinders.Binderswith a given type you want to bind to. This is the preferred way for me, as it doesn’t require additional decorations for my models. However, it does have some limitations.
Registering your model binders via the model binders dictionary requires that you specify a model you will bind to. This means you have to specify all your model binders at application start, but in many situations you may want to be handle this dynamically. Moreover, it doesn’t give you much flexibility in terms of when you want to do the binding: you are forced to always provide the same binding to the same model type. To address these limitation, I have created a simple extension to the model binding mechanism.
You can define an interface,
IExtendedModelBinder, with these two methods –
public interface IExtendedModelBinder
bool CanBindModel(ControllerContext controllerContext,
object BindModel(ControllerContext controllerContext,
Furthermore, you can inherit from
DefaultModelBinder, which as the name suggests is the default model binder, the following way:
public class DefaultExtendedModelBinder : DefaultModelBinder
private readonly IEnumerable _modelBinders;
if (modelBinders == null)
throw new ArgumentNullException("modelBinders");
_modelBinders = modelBinders;
public override object BindModel(ControllerContext controllerContext,
foreach(IExtendedModelBinder modelBinder in _modelBinders)
if (modelBinder.CanBindModel(controllerContext, bindingContext))
return modelBinder.BindModel(controllerContext, bindingContext);
return base.BindModel(controllerContext, bindingContext);
The last thing is to replace the default model binder with our custom version. You can either explicitly create instances of all your extended model binders or use a dependency container to do this for you. I tend to do the latter.
ModelBinders.Binders.DefaultBinder = new DefaultExtendedModelBinder(...);
Model binding abstracts away the tedious mapping logic for your models. It makes your controllers clear and devoted on your presentation logic only, which is to fetch data and create specific view models for your views.