LA.NET [EN]

Sep 10

The MVC framwork – model binders

Posted in ASP.NET MVC      Comments Off on The MVC framwork – model binders

In the last post of the series, we’ve seen how the default ControllerActionInvoker is responsible for performing the hard work associated with the execution of the specified action method. At the time, we’ve also seen that parameter values that are passed to the action method are recovered through the use of a model binder. A model binder is a new concept introduced in this release that will let you associate a class that implements the IModelBinder interface with a parameter expected by an action method. Before seeing how this is done, lets start by inspecting the IModelBinder interface. In the current implementation, it only has one method:

public interface IModelBinder {
        object GetValue(ControllerContext controllerContext, string modelName, Type modelType, ModelStateDictionary modelState);
}

The GetValue method is used when the platform tries to recover the value of parameter. As you can see, the method receives a reference to the ControllerContext, current method name, parameter type and a reference to the current model state. Currently, the platform introduces two model binders: DefaultModelBinder and the DateTimeModelBinder. The last is used when you have a parameter of type DateTime or DateTime?. The first is used by default when you don’t associate a parameter to a specific binder or when you don’t have a DateTime parameter.

As we’ve said before,you can associate a specific IModelBinder to a parameter. You can also associate it with a class. You do this by using the ModelBinderAttribute. Lets suppose you’ve built a specific binder that you want to associate to a MyType parameter. Here’s an example that shows how this can be done:

public ActionResult( [Binder(typeof(MyModelBinder))]MyType parameter);

As I’ve said,you can also apply that parameter to a class if you have several action methods which expect parameters whose value should be recovered through the use of that specific model binder.

Besides associating a model binder to a specific parameter/class, you can also associate a model binder with a specific type (ie, you can build your own binders that work with a specific parameter type). In these cases, you need to register it with the ModelBinders static class (generally, you’ll do this when the web app “starts”). Lets suppose that instead of registering the previous model binder (MyTypeBinder) with a specific parameter you want to use it with all the parameters of a MyType. To do that you’ll need something like this:

ModelBinders.Binders.Add( typeof(MyType), new MyModelBinder() );

This approach is good whenever you have lots of parameters whose values should be recovered by this model binder and these parameters are used by action methods scattered through several controllers.

You have two options when building your own model binders. You can simply implement the IModelBinder interface and then you’re responsible for recovering the values you need and building a new instance of the type (for instance, you can get the needed value from the RouteData.Values collection, from the querystring collection, from the form collection, etc…you get the idea!). There’s also another option: you can extend the DefaultModelBinder class and override the ConvertType method. The advantage of doing this is that you’ll be able to reuse the base implementation of the GetValue method that will try to get the value of the parameter from one of the predefined sotages (RouteData, query string and then form).And I guess that it’s all for today.

More about the MVC on the next posts. Keep tuned!