Asp.Net MVC 2 DefaultModelBinder ошибка с использованием абстрактных классов - PullRequest
4 голосов
/ 05 марта 2010

У меня есть простая Poco-модель, использующая абстрактные классы, и она, похоже, не работает с моделью ModelBinder по умолчанию в Asp.net MVC 2. Один элемент имеет несколько объектов в коллекции, каждый из которых использует один и тот же абстрактный базовый класс.

Модель:

    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;

Используя помощник по умолчанию Html.EditorForModel () для этого элемента с одним TextObject в коллекции объектов, я получаю поле ввода html, подобное этому:

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

При отправке обратно в контроллер я получаю сообщение об ошибке «Невозможно создать абстрактный класс» из DefaultBinder Model. Очевидно, связыватель пытается создать экземпляр этого абстрактного базового класса. Но я не знаю почему, так как в коллекции есть только объект унаследованного типа TextObject. Есть ли другой способ заставить это работать без написания собственного Modelbinder?

Ответы [ 3 ]

3 голосов
/ 05 марта 2010

Вам нужно будет использовать пользовательское связующее для моделей или использовать модели представления.Связыватель модели знает только о типе, который вы используете в качестве параметра для вашего действия (содержит абстрактный класс).Затем он пытается отобразить значения из запроса в эту модель.Нет никакого способа, которым связыватель мог бы знать, что он должен использовать какую-то другую реализацию и какую реализацию это может быть.

Мой совет - создавать упрощенные модели представления и отображать их с помощью automapper .

2 голосов
/ 22 июня 2010

Проверьте DerivedTypeModelBinder в MvcContrib. TypeStamping внедряет метаданные в рендеринг представления, давая производной typemodelbinder информацию, необходимую для правильного вызова объекта, который нужно создать. Более длительное обсуждение со ссылками на этот

MVC2 Modelbinder для Списка производных объектов

0 голосов
/ 05 марта 2010

Я думаю, вам нужно указать в классе Item коллекцию объектов как ICollection<TextObject>.В противном случае связыватель модели по умолчанию не сможет понять, какой объект он должен создать.Если вы решите создать пользовательский связыватель модели, вам нужно будет добавить в форму для каждого объекта поле, указывающее его тип.Привет.

...