views:

89

answers:

2

I'm scratching my head a bit at how model binders do their work in ASP.Net MVC.

To be specific, the BindModel() method has a ModelBindingContext parameter that holds the model name and type, but I don't understand how the ModelBindingContext receives these values.

An MVC model has to be populated from posted form values or query string parameters, or other sources of data. But what mechanism determines the model type handed to the ModelBindingContext, and how is one model type chosen over another model type, over even (say) a simple list containing the individual posted values?

It just appears to me the ModelBindingContext "knows" the type of model it's being handed, and I'm not sure where that's coming from or the workflow involved in populating it.

+1  A: 

The ModelBindingContext "knows" the type of model it's being handed because you have to either:

  • Add a ModelBinder attribute to your model
  • Register the ModelBinder with your model using the ModelBinders.Binders.Add() method.

Example of ModelBinder attribute:

[ModelBinder(typeof(ContactBinder))] public class Contact { ... }

Example of ModelBinders.Binders.Add():

void Application_Start() { ModelBinders.Binders[typeof(Contact)] = new ContactBinder(); }

If you have registered your ModelBinder and have implemented the BindModel method:

public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { ... }

  1. Query the ModelBindingContext.ModelType is equal to your Model e.g.
    if (bindingContext.ModelType == typeof(Contact)) { ... }

  2. Rehydrate your model from the ModelBindingContext.ValueProvider property to retrieve ValueProviderResult instances that represent the data from form posts, route data, and the query string e.g. bindingContext.ValueProvider["Name"].AttemptedValue;

The following books were used ASP.NET MVC 2 in Action and ASP.NET MVC 1.0 Quickly

Clive Seebregts
larryq
+1  A: 

Interesting question. Here is a simple overview of what MVC does. It's all handled by the ControllerActionInovker class. This is not in specific order, but is close.

  1. ControllerActionInovker determines the parameter type via reflection.
  2. Next ValueProviders are created from the HttpContext Request Form, Route, QueryString, etc. properties. You can also provide your own value providers.
  3. These ValueProviders are supplied to a ModelBindingContext via a collection that acts as a virtual ValueProvider.
  4. Then ControllerActionInovker looks for a ModelBinder for the specific type. If it doesn't find one it defaults to the built in DefaultModelBinder.
  5. In most cases the DefaultModelBinder is used. It's job is to create a Model, and use the ValueProviders to connect the properties with values using the model properties names as a key. When the ValueProviders have a value, they return a ValueProviderResult object that is responsible for type conversion.

You can see this for yourself in the ASP.net MVC source located at codeplex.com. Look for the ControllerActionInvoker class and the GetParameterValue method.

Lynn Eriksen
Thanks for the summary
larryq