Подтвердить что ты не робот

Есть ли веские основания использовать FormCollection вместо ViewModel?

Я унаследовал базу кода, написанную в ASP.Net MVC 4. Каждый метод post принимает значение FormCollection. Помимо раздражения от необходимости доступа к значениям посредством цитируемых строк, это также приводит к недостаткам, таким как невозможность использования таких объектов, как ModelState.IsValid или [AllowHtml] атрибуты в моих свойствах ViewModel. Они действительно создавали классы ViewModel для каждого из своих представлений (хотя они в значительной степени просто прямые обертки вокруг реальных классов модели Entity Framework), но они используются только для методов GET.

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

Но, возможно, там что-то мне не хватает, когда имеет смысл использовать FormCollection?

4b9b3361

Ответ 1

Есть ли веские основания использовать FormCollection вместо ViewModel?

Нет. У меня есть следующие проблемы.

Проблема - 1

В случае использования FormCollection... Обязательно Type Cast Primitive Type Значения необязательно, потому что, получая запись определенного индекса System.Collections.Specialized.NameValueCollection, возвращаемое значение имеет тип String. Эта ситуация не наступит в случае строго типизированного View-Models.

Проблема - 2

При отправке формы и перехода к Post методу действия и View-Model в качестве параметра существует метод Action, у вас есть условие для отправки назад к вам добавленных значений View. В противном случае напишите код еще раз, чтобы отправить обратно через TempData/ViewData/ViewBag

enter image description here

View-Models - обычные классы, созданные для привязки данных к-из представлений

Проблема - 3

У нас есть аннотации данных, которые могут быть реализованы в View Model или Custom Validations.

enter image description here

ASP.Net MVC упрощает моделирование валидатов с использованием Data Annotation. Аннотации данных - атрибуты, которые применяются к свойствам. Мы можем создать собственный атрибут проверки, наследуя встроенный класс атрибутов проверки.



Проблема - 4

Например, у вас есть следующий HTML

<input type="text" name="textBox1" value="harsha" customAttr1 = "MyValue" />

Вопрос. Как мы можем получить доступ к значению customAttr1 из вышеприведенного, например, изнутри контроллера

Ответ: при отправке формы только имя и значение элементов отправляются обратно на сервер.

Альтернативы. Используйте бит jQuery для получения значений пользовательских атрибутов и отправьте их вместе со значениями формы в метод действий

Другой вариант - скорее разместить то, что вы получили в пользовательских атрибутах в скрытых элемента управления.




В этой причине я всегда предпочел бы использовать View-Models

Ответ 2

Единственное преимущество, о котором я могу думать, - это если вы хотите использовать автоматически созданный контроллер, если вы не укажете, какую модель EF будет строго типизирована. В этом случае ваши действия "Создать и редактировать" будут использовать объект FormCollection, поскольку он является надежным, уже существующим артефактом фреймворка для работы с этой целью. Возможно, предыдущий разработчик выбрал этот вариант при создании своих контроллеров и застрял с ним, поскольку Visual Studio должна знать, что он делает:)

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

Ответ 3

Хорошо, я вижу, что общий консенсус здесь заключается в том, что он не нравится. Чтобы предложить другую перспективу, мне всегда нравилось использовать formcollection, переданный контроллеру при действиях POST. Он предлагает использовать метод TryUpdateModel от контроллера, который отобразит коллекцию в строго типизированный класс. В TryUpdateModel также есть перегрузки, которые позволяют вам белым перечислять свойства модели, которые вы хотите разрешить обновлять.

if (TryUpdateModel(viewModel, new string[] { "Name" }))
{
    //Do something
}

Он по-прежнему разрешает все привязки модели, которые вы хотите, но помогает сохранить что-либо, кроме свойства "Name" на моей модели viewmodel, из-за обновления.

Здесь вы можете узнать больше о методе TryUpdateModel:

http://msdn.microsoft.com/en-us/library/system.web.mvc.controller.tryupdatemodel(v=vs.108).aspx

Ответ 4

Всегда есть обходные пути для того, чтобы уйти от FormCollection lol.. у вас могут быть скрытые поля, привязанные к вашим переменным модели вида в форме, к вашему сердечному содержимому.

Коллекции форм чаще всего выходят из лени, создавая модель представления, но все же в конечном итоге занимают время, пытаясь выяснить, как получить значения из этого в вашем контроллере: P

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

Может быть, вы можете использовать его, если абсолютно уверены, что у вашего представления никогда не будет более одного ввода формы? Наверное, все-таки плохая идея, хотя..

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

Ответ 5

Да. Иногда это может быть полезно. Вот пример:

Скажем, мы имеем в нашем db "date_and_time_field".

В Razor View мы хотим использовать два поля формы. Первая "Дата" (возможно, с jQuery UI Datepicker). Второй "Час".

В действии Controller мы создаем "date_and_time_field" с помощью Request.Form["Date"] и Request.Form["Hour"].

Существуют и другие сценарии, где это может быть полезно:

  • Перекрестный стол (с checkBoxes в представлении Razor)

  • Коллекция Request.Unvalidated().Form (может быть, это не часть вашего вопроса: я не хочу быть вне темы)

Ответ 6

Связующее устройство по умолчанию сделает почти все, что вам нужно. Я обратился к FormCollection один раз - только позже, чтобы понять, как связать массивы элементов в коллекции на ViewModel.

Просто перейдите в ViewModel. Лучше всего вокруг, по каждой причине перечислены.

Ответ 7

С помощью form collection вы сможете получить все значения внутри формы. Могут быть ситуации, когда вам может потребоваться передать некоторые дополнительные значения из формы, которая не может быть частью вашего view model.

Просто возьмите пример передачи 10 скрытых значений из формы. Коллекция форм имеет смысл.

Единственная трудность, с которой вы можете столкнуться, - это литье типов. Все элементы коллекции форм, которые вы получите, будут строками; вам может потребоваться type cast на основе вашего требования.

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

Ответ 8

Хорошо с Сбор форм вы найдете быстрый способ получить значения формы. В противном случае вам нужно создать класс, который имитирует поля формы, и люди когда-нибудь ленится создавать пользовательские классы для менее важных/редко используемых форм.

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

Ответ 9

Вы всегда можете добавить свойства коллекции форм к вашим подписям методов. Они будут автоматически заполнены значениями формы с помощью соответствующих клавиш.

Ответ 10

Отвечая на вопрос заголовка: да.

Есть некоторые ситуации, которые необходимо использовать FormCollection. Например, предположим, что ViewModel, обладающее свойством, которое реализует отношение от 1 до N (в конкретном случае a TimesheetViewModel с ICollection<TimesheetEntryViewModel>), и Контроллер должен выполнить проверку между записями времени, чтобы не получить временное столкновение между временем окончания записи и временем начала следующей записи. Как пометить связанную запись с ошибкой проверки, как можно получить индекс строки?

Ну, при привязке модели по умолчанию значение индекса теряется в логике контроллера. К счастью, FormController хранит индекс, который вы использовали в представлении, и может быть выполнена более конкретная проверка.