Что такое корректное поведение UpdateModel в ASP.NET MVC?

Мне интересно узнать, что вы, ребята, чувствуете, должно считаться "правильным поведением" с точки зрения метода UpdateModel в ASP.NET MVC.

Причина, по которой я спрашиваю, может быть, если эта функциональность "по дизайну", кто-то может уточнить, почему она такая, какой она есть, и, возможно, способ назвать ее по-другому для достижения желаемой функциональности, которую я бы себе представлял как 90% людей захотят, чтобы это работало?

В сущности, моя проблема заключается в поведении процесса привязки в UpdateModel.

Предположим, что вы хотите обновить форму с помощью простого метода действий Save, для которого поля данных в форме отражают модель в вашей базе данных, изначально для сохранения запроса, мы могли бы получить существующую модель из базы данных, а затем обновить соответствующие поля, которые были изменены, отправлены через FormCollection, а затем обновлены UpdateModel к нашей существующей модели. Это работает, однако, похоже, что любое из существующих свойств этого объекта, заполненного БД, является "reset"; и под этим я имею в виду, устанавливаются значения null или инициализации по умолчанию, как если бы это был совершенно новый объект, за исключением, очевидно, тех, которые соответствуют значениям в FormCollection.

Это проблема, потому что любые существующие свойства, которые существуют на объекте, но необязательно существуют в форме, такие как дочерние коллекции или объекты, даты или любые поля, не относящиеся к интерфейсу UI, пусты, более или менее непригодный для использования объект, который не может быть сохранен в БД из-за всех отсутствующих данных, включая, вероятно, стек идентификатора, теперь установленного на 0.

Я считаю, что это нежелательное поведение, а UpdateModel должно только обновлять свойства, где находит соответствие свойства в FormCollection. Это означает, что все ваши существующие свойства будут не затронуты, но ваши обновления будут установлены. Однако из того, что было выведено до сих пор, очевидно, это не так - кажется, он создает экземпляр новой копии объекта, обновляет свойства из формы, а затем возвращает новый объект.

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

Я думаю,

  • Те, кто согласен с этим по дизайну, - это мой подход к форме, выйдя замуж за лучший способ?
  • Или, как вы справились с этим в этом?

Пожалуйста, не стесняйтесь предлагать свои мысли этим парням, спасибо.

Вот еще один пример того, кто страдает от этой проблемы:
Вызов UpdateModel с набором сложных типов данных reset все не связанные значения?

Ответы

Ответ 1

Поведение, которое вы испытываете с помощью UpdateModel(), похоже на то, что вы привязываетесь к списку, и в этом случае UpdateModel() удалит содержимое списка и повторно закроет его. См. блог Hanselman для обсуждения этого вопроса. Если вы обновляете один объект, UpdateModel() будет обновлять этот отдельный объект, оставив свойства, у которых нет соответствующего значения формы as-is.

Многие из этих проблем сводятся к тому, что UpdateModel() действительно предназначен для репопуляции моделей представлений, а не моделей доменов, основанных на вводе формы. (Я немного упрощаю ситуацию, говоря, что модель представления - это всего лишь контракт между контроллером и представлением, в то время как ваша модель домена может быть объектом модели LINQ2SQL или EF.) Все учебники и демонстрации MVC показывают, что UpdateModel() является используется для объектов базы данных, что, по моему мнению, является неудачным, поскольку оно несколько вводит в заблуждение относительно предполагаемой цели привязки модели. Сообщение Robert больше указывает на фактическое намерение UpdateModel().

Ответ 2

Я считаю, что вы правы в поведении UpdateModel.

Однако ASP.NET MVC следует модели "туда и обратно", что означает, что ваша форма должна содержать все поля, необходимые для создания полной записи, либо потому, что вы ввели значения для всех полей в представление, или вы запрашиваете все поля от пользователя.

Эта концепция "туда и обратно" очень важна. Помните, что в настоящей модели MVC нет понятия состояния. Вы извлекаете данные из таблицы базы данных, перетаскиваете эти данные в представление, данные отображаются пользователю, а программа останавливается. Пользователь редактирует данные, нажимает кнопку "Опубликовать", данные просмотра публикует данные по методу контроллера, данные сохраняются в базе данных, и программа останавливается. Никаких зависимостей от одной операции до следующей нет.

Эта практика несоблюдения частичного состояния записей и структур данных делает очень простой способ писать приложения, которые хорошо масштабируются и хорошо себя ведут (особенно в отношении таких вещей, как кнопка "Назад" в браузере).

Ответ 3

Я использую UpdateModel довольно счастливо для типов без списка. Я всегда стараюсь указать массив includeProperties (не из-за возможности этой проблемы, но для безопасности - хотите ли вы, чтобы пользователь мог взломать форму (очень просто) и отправить даты и т.д.?).

Чтобы не сказать, что это не может быть улучшено дальше.

Кроме того, практический момент, который следует учитывать при настройке требований: для веб-сервера, получающего POST, пустое поле совпадает с несуществующим полем. Это означает, что если UpdateModel был спроектирован таким образом, что в нем не было "reset" несуществующих полей формы (например, дата), то такое же поведение означало бы, что если пользователь удалит текст в вашем поле даты и сообщениях, это не будет обновить с пустым (или нулевым).

Джеймс

Ответ 4

Но я все еще борюсь с идеей представляя всю мою объектную модель в форма, особенно если у меня было 2 дочерние объекты и несколько списков, Я не уверен, как это легко будет сопоставлен; Стек скрытых поля, изображающие весь объект карта? Просто кажется странным.

Для этого вам нужно изучить такие вещи, как SubControllers и RenderAction. Вы можете использовать Google. Я много использую RenderAction. Это позволяет мне вводить виджет на страницу из своего собственного метода контроллера, не вставляя отдельные данные в ViewData.

Я не думаю, что нужно быть уверенным гарантировать любые данные, которые вы хотите обновить к вашей модели БД, должен существовать полностью на форме. Я не думаю, что я иметь одну таблицу db, которая могла бы облегчить это, рассмотреть "создание дата", например, или "обновленная дата", Я не думаю, что было бы идеально сохраните это в скрытом поле на форма.

Вы правы в этом. Такие вещи, как CreationDate, UpdateBy, должны обрабатываться в контроллере (на самом деле репозиторий, если вы используете репозитории). К тому времени у вас должно быть все поля, которые вам нужны, из модели просмотра, чтобы обновить вашу базу данных.

Возможно, вам придется использовать объекты с сильно типизированной моделью просмотра. Если вы этого не сделаете или не уверены, просмотрите эту страницу: http://nerddinnerbook.s3.amazonaws.com/Part6.htm