Search code examples
asp.net-mvc-2abstract-classdefaultmodelbinder

Asp.Net MVC 2 DefaultModelBinder error using abstract classes


I have a simple Poco-Model using abstract classes, and it seems not to work with the Default ModelBinder of Asp.net MVC 2. One Item has several Objects in a collection, all using the same abstract base class.

Model:

    public partial class Item
    {  
        public virtual ICollection<Core.Object> Objects
        {
            get
            {
                return _objects;
            }
            set
            {                
                    if (value != _objects)
                    {
                        _objects = value;
                    }
            }
        }
        private ICollection<Core.Object> _objects;
    }   


 public abstract partial class Object
    {

        public virtual Item Item
        {
            get
            {
                return _item;
            }
            set
            {
                if (!Object.ReferenceEquals(_item, value))
                {
                    _item = value;
                }
            }
        }
        private Item _item;       

    }

    public partial class TextObject : Object
    {
        public virtual string Text { get; set; }
    }

Instance:

var NewItem = new Item();                    
var TextObject1 = new TextObject
{
   Text = "Text Object Text",
   Item = NewItem
};                      
List<Core.Object> objects = new List<Core.Object>(){TextObject1};            
NewItem.Objects = objects;

Using the Default Html.EditorForModel() Helper for that item with one TextObject in the Objects collection I get a html input-field like that:

<input class="text-box single-line" id="Objects_0__Text" name="Objects[0].Text" type="text" value="Text Object Text" />

When posting back to the Controller I get an "Cannot create an abstract class" Errormessage from the Default ModelBinder. Obviously the binder tries to instantiate that abstract base class. But I don't know why, since there are is only an object of the inherited TextObject type in the collection. Is there any other way to get this working without writing a custom Modelbinder?


Solution

  • You will have to use a custom model binder or use viewmodels. The model binder only knows about the type that you use as a parameter to your action (contains the abstract class). Then it tries to map values from the request to that model. There is no way the binder could know that it should use some other implementation and what implementation that might be.

    My advice is to create viewmodels that are simpler and map them using automapper.