views:

220

answers:

2

I have a hierarchy of classes that all derive from a base type and the base type also implements an interface. What I'm wanting to do is have one controller to handle the management of the entire hierarchy (as the actions exposed via the controller is identical). That being said, I want to have the views have the type specific fields on it and the model binder to bind against a hidden field value. something like:

<input type="text" name="model.DerivedTypeSpecificField" />
<input type="hidden" name="modelType" value="MyDerivedType" />

That being said, the asp.net mvc model binders seem to require the concrete type that they will be creating, because of that reason I would need to create a different controller for every derived type.

Has anyone does this before or know how to manipulate the model binder to behave in this way? I could write my own model binder, but I'm not wanting anything past the basic model binding behavior of assign properties and building arrays on the target type.

Thanks!

+2  A: 

Don't know if it will work, but you can try something like:

public class MyBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        bindingContext.ModelType = System.Type.GetType(controllerContext.HttpContext.Request["modelType"]);

        return base.BindModel(controllerContext, bindingContext);
    }
}

That is just simple change of basic model binder.

LukLed
I figured it out. My solution is almost identical to yours except I'm grabbing the modelType out of ValueProviders array. Thanks!
Sean Chambers
A: 

Check out the Derived Type ModelBinder in MvcContrib. This allows you to modelbind to derived types through the process of 'typestamping' - which is handled automatically for you when using the RenderTypedPartial(...) helper. MvcContrib partials maintain binding state across partials so the Name/Id prefixes are properly maintained on a deep object graph. If you use other mechanisms like templates, then you'll need to handle the typestamping yourself. This is explained in the documentation page.

Getting back to your questions and how the derived types are resolved with the ModelBinder, you can register the derived type variations with attributes in a mechanism similar to the WCF KnownTypeAttribute or you can do the registration on startup. Either way, these variations are registered once and held onto for performance considerations.

The model binder also solves this problem in a way that does not interfere with data annotation/validation attributes. They will work as you expect them in any other scenario.

S. Hebert