asp.net mvc - строго типизированные помощники - должен ли ваш объект привязки рендеринга быть таким же, как ваш объект публикации?

Я вижу, что asp.net mvc 2 сильно помог мне с типизацией, и, глядя сначала на то, как он работает, я думаю, что, возможно, я делаю что-то не так в asp.net mvc 1 с точки зрения привязки данных для визуализации представления и отправки обратно на контроллер.

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

например, на пути к визуализации моя модель представления может выглядеть так

 public class PersonViewModel
 {
      public int Age;
      public string FIrst;
      public JobCategory[] JobCategories;
      public Sport[] Sports;
      public int NumberOfChildren;

 }

в этом случае jobCategories и Sports будут использоваться для заполнения выпадающего списка. NumberOfchildren будет просто вставлен HTML, и я не хочу, чтобы он редактировался. Когда я хочу опубликовать, я хочу передать только тонкий объект с только опубликованными свойствами, поэтому у меня есть другой объект

  public class PersonUpdater
 {
      public int Age;
      public string FIrst;
      public int JobCategoryId;
 }

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

 public ActionResult Update(PersonUpdater personUpdater)
 {
      _repository.UpdateModel(personUpdater). 
 }

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

http://weblogs.asp.net/scottgu/archive/2010/01/10/asp-net-mvc-2-strongly-typed-html-helpers.aspx

Какие-нибудь мысли?

7 ответов

Решение

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

Люди еще не приняли деление view model в, как я их называю, input view model а также output view model (для многих - даже создание view model слой это слишком много). Поэтому - Mvc2 в настоящее время не имеет поддержки для этого (у вас не должно быть строго типизированного представления, которое не является вводом и выводом одновременно) в основном из-за неопределенности и отсутствия общепринятых подходов.

Но я думаю, что есть преимущество (хорошо... это на самом деле компромисс) в углублении и разделении view model на 2 из них. И я не удивлюсь, если эта идея будет развиваться и в конечном итоге станет широко принятой.

На самом деле - у нынешнего подхода даже есть название - принцип Thunderdome. И если такие ребята, как Джереми Д. Миллер, говорят, что это правильно, сообщество не будет беспокоиться и не будет искать ничего другого.


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

Просто глядя на вашу конкретную ситуацию, мне приходят в голову следующие моменты.

1) Две модели очень похожи действительно 2) Если вы добавляете "MiddleName", вы должны добавить его в двух местах 3) Когда вы говорите "Я только хочу вернуть тонкий объект" - фактический POST будет содержать то же самое объем данных, независимо от того, привязаны ли вы к исходной модели или к новой (она будет содержать ключ, пару значений для каждого пользовательского ввода в форме) 4) Вы исключаете возможность отображения данных в своем "сохраненном порядке" или страница "что-то не верно", поскольку она не является частью модели

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

Вы можете указать, на какое свойство вы ссылаетесь, в строго типизированном помощнике, ищите перегрузку с 3 параметрами.

Ничего плохого в вашем методе. Строго типизированные представления помогут вам лучше развиваться, так что ни один типо не сможет помешать вам.

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

Я использую отдельные модели представления для ввода [GET] и вывода [POST], если только эти две модели не идентичны. ИМХО, этот подход чище, проще в обслуживании и более четко выражает, какие данные будут обновляться с помощью данного действия контроллера.

С точки зрения LOC, это обходится дорого, но дополнительный код обычно не логичен. В большинстве случаев я не чувствую, что дублирование некоторых автоматических свойств на двух объектах нарушает принцип СУХОЙ, и я думаю, что цена оправдана для следования SRP.

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

Я бы посоветовал сделать это проще, просто используя один объект для GET и POST. Поддерживаемость кода здесь гораздо важнее / ценнее, чем сохранение нескольких байтов для действия обновления.

Арнис приводит хорошие аргументы в отношении SRP и других шаблонов дизайна, но предполагается, что petterns должны быть адаптированы. Если бы я был тобой, я бы использовал помощь, созданную фреймворком mvc: используй типизированные помощники; используйте типизированные объекты model/viewmodel для GET/POST и, если вам нужно более сложное связывание, создайте пользовательское связующее.

Держите ваш код легким, и ваше приложение останется замечательным.

В большинстве случаев материалы с автоматической привязкой не соответствуют тому, что мне нужно, поэтому я просто прибегаю к публикации в formCollection Параметр и иди в ручную. Если вы можете использовать любую часть магии привязки модели, тогда вам будет лучше.

Связывание меньше не означает, что меньше данных отправляется обратно на сервер. Все входные элементы в форме будут переданы, вы просто не увидите их как дискретные, строго типизированные, "автоматические" параметры. Если вы действительно хотите уменьшить объем публикуемых данных, вы должны ограничить элементы ввода внутри конкретной формы, которую вы публикуете. MVC все еще HTTP...

Другие вопросы по тегам