views:

484

answers:

1

I want a list of different (derived) object types working with the Default Modelbinder in Asp.net MVC 2.

I have the following ViewModel:

public class ItemFormModel
    {       
        [Required(ErrorMessage = "Required Field")] 
        public string Name { get; set; }
        public string Description { get; set; }

        [ScaffoldColumn(true)]
        //public List<Core.Object> Objects { get; set; }       
        public ArrayList Objects { get; set; }                  
    }

And the list contains objects of diffent derived types, e.g.

public class TextObject : Core.Object
    {
        public string Text { get; set; }
    }

    public class BoolObject : Core.Object
    {
        public bool Value { get; set; }
    }

It doesn't matter if I use the List or the ArrayList implementation, everything get's nicely scaffolded in the form, but the modelbinder doesn't resolve the derived object type properties for me when posting back to the ActionResult.

What could be a good solution for the Viewmodel structure to get a list of different object types handled? Having an extra list for every object type (e.g. List, List etc.) seems to be not a good solution for me, since this is a lot of overhead both in building the viewmodel and mapping it back to the domain model.

Thinking about the other approach of binding all properties in a custom model binder, how can I make use the data annotations approach here (validating required attributes etc.) without a lot of overhead?

+3  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