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.
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.
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.
The way I see it is that ControllerActionInvoker uses reflection to get the parameter type, it then checks if any ModelBinder is assigned to deal with that type, if so it instantiates this ModelBinder and passes it the BindingContext which will contain the (model object, model name, model type, property filter) for that parameter type object and a value provider collection (ModelBindingContext.ValueProvider) of all other value providers (Form, Query String etc.), acting as one big virtual value provider.
The ModelBinder then itself uses reflection to get all property names for the type its assigned to bind and runs itself recursively against all the value providers in (ModelBindingContext.ValueProvider) and looks for the property names in those value providers, binding those values for whom the names (taken from client) match the type property names, when they match the value provider returns a ValueProviderResult object, bearing the name and value for the respective property on the model.
The ModelBindingContext "knows" the type of model it's being handed because you have to either:
Example of ModelBinder attribute:
Example of ModelBinders.Binders.Add():
If you have registered your ModelBinder and have implemented the BindModel method:
Query the ModelBindingContext.ModelType is equal to your Model e.g.
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.
The following books were used ASP.NET MVC 2 in Action and ASP.NET MVC 1.0 Quickly