MVC3 ModelBinder для DynamicObject

Я ищу, есть ли образец проекта, учебник, ветка contrib или что-то в этом роде, в котором подробно описывается реализация настраиваемого ModelBinder для MVC3 для поддержки объектов, унаследованных от DynamicObject.

У меня есть объект домена, который имеет динамическое количество свойств, определенных базой данных, и они могут изменяться во время выполнения. Чтобы упростить использование объекта, я сделал реализацию моего класса унаследованной от DynamicObject и передаю модель в представление через ключевое слово [dynamic].

Все динамические свойства объекта находятся в свойстве коллекции объекта, называемом «Атрибуты». Я хотел бы создать серию шаблонов редактора, чтобы конкретизировать модель, в идеале, поэтому все, что мне нужно сделать, это сделать вызов в соответствии со строками Html.EditorForModel (), и он будет динамически создавать пользовательский интерфейс.

Проблема в том, что мне не очень повезло с поиском реализации ModelBinder, способной проверять DynamicObject и строить UI (я думаю, это правильный термин для этого?).

Я нашел проект IDictionary ModelBinder, сделанный в одном из видеороликов MVCConf, сделанных Роберто Эрнандесом (@hernandezrobert) на Расширяемость MVC3 (источник на http://mvcextensibility.codeplex.com/), но мне не очень повезло с его адаптацией к моим целям. Мне было интересно, пытался ли кто-нибудь еще создать привязку модели, способную делать то, что я описываю? Или может указать мне правильное направление?


person Nick Albrecht    schedule 01.03.2011    source источник


Ответы (2)


ModelBinders не помогает сгенерировать представление, они помогают сопоставить необработанные параметры из различных веб-источников (форма, строка запроса и т. Д.) С входными параметрами, ожидаемыми вашим методом действия (в частности, если ваши входные параметры являются классом некоторых сортировка, а не примитивы).

То, что вы ищете, - это пример того, как создавать шаблоны представления, которые я не видел для динамики. Лучшим ресурсом для создания шаблонов регулярных представлений, который я видел, является Блог Брэда Уилсона. Если у вас есть средство (которое, похоже, есть у вас) выяснить, какие свойства объект должен отображать вместе с метаданными о том, как их отображать (например, текстовое поле или тип ввода = текст и т. Д.), Тогда вы должны иметь возможность просто следовать за Брэдом.

person Paul    schedule 01.03.2011
comment
Похоже, это может сработать, но мне все равно понадобится ModelBinder / MetaDataProvider для аспекта проверки при отправке данных обратно в контроллер. - person Nick Albrecht; 01.03.2011
comment
Да, вот тут-то и пригодится привязка моделей. Вероятно, проще всего, если ваш настраиваемый динамический объект просто принимает словарь строки, объекта в качестве фабричного метода или в перегрузке construcotr, тогда ваш привязщик моделей может просто передать это. - person Paul; 01.03.2011
comment
Я думаю, что ModelBinder также используется для построения представления. Когда я пытаюсь автоматически создать пользовательский интерфейс для представления с помощью EditorForModel (), он сгенерировал поля правильно, но как только я зарегистрирую свой собственный ModelBinder на основе упомянутого выше проекта расширяемости, EditorForModel () перестает работать должным образом. Может быть, он используется, когда вы используете EditorForModel () или EditorFor ()? - person Nick Albrecht; 02.03.2011

Я смог решить свою ситуацию, настроив обычный класс, который будет служить моделью для моего DanamicObject, и сохранив мои свойства таким образом

IList<DynamicProperty> DynamicProperties { get; set; }

Я создал настраиваемое представление для DynamicObject, и в этом представлении я вызвал одного из помощников, чтобы отобразить свойство DynamicProperties. Это позволяет MVC перебирать коллекцию и отображать каждое свойство. Затем у меня есть представление для DynamicProperty, которое я использую для рендеринга свойства по мере необходимости. Ключ в том, что вам также необходимо отобразить скрытое поле, содержащее первичный ключ этого конкретного атрибута. ModelBinder в MVC3 выполняет здесь гораздо лучшую работу, чем в MVc2, поэтому он будет отображать индекс массива как часть имени поля, так что первичный ключ и значение каждого свойства правильно объединяются в пары при отправке. Скорее всего, вы захотите создать ViewModel специально для отправленных данных, у меня были проблемы, когда я пытался использовать тот же класс модели, что и в представлениях сведений / редактирования, потому что я визуализировал только подмножество полей, поэтому они отсутствовали, когда я привязался к тот же класс Model при обратной передаче.

Вы можете обрабатывать сохранение, как обычно, но есть несколько соображений безопасности для этого типа объекта. Поскольку количество атрибутов является динамическим, невозможно гарантировать, что будет отправлено то же количество полей, что и было изначально отображено. Пользователь может ввести свои собственные или, что еще хуже, добавить поля для свойства, которое вы, возможно, явно исключили. AntiForgeryToken предотвратит отправку подобного рода за пределами вашего домена, но из-за простоты и популярности манипуляций с DOM, предоставляемых такими библиотеками, как jQuery, межсайтовые обратные передачи - не единственные проблемы, и я не знаю, будет ли AntiForgeryToken учитывать но я в этом сомневаюсь.

Этот подход оказался проще, чем попытка наследования от DynamicObject, реализация GetDynamicMemberNames и создание настраиваемого ModelBinder для использования обтекания.

Однако я создал собственный поставщик ModelMetaData и Validation Provider для обработки этих аспектов, поскольку свойства не являются строго типизированными, поэтому у MVC не было никаких аннотаций для использования.

person Nick Albrecht    schedule 30.03.2011