Что такое правильное поведение UpdateModel в ASP.NET MVC? - PullRequest
17 голосов
/ 07 августа 2009

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

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

В сущности, моя хватка связана с поведением процесса связывания внутри UpdateModel.

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

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

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

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

Я думаю,

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

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

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

Ответы [ 4 ]

15 голосов
/ 07 августа 2009

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

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

5 голосов
/ 07 августа 2009

Полагаю, вы правы относительно поведения UpdateModel.

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

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

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

2 голосов
/ 08 августа 2009

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

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

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

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

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

2 голосов
/ 07 августа 2009

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

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

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

1009 * Джеймс *

...