Передача пользовательского объекта ViewModel в ActionMethod против передачи в виде FormCollection
Очевидно, что реальные приложения намного сложнее, но для примера скажем, у меня есть следующее простое представление, и мне нужно сохранить пользователя:
@model UserViewModel
@Html.TextBoxFor(model=>model.FirstName)
</br>
@Html.TextBoxFor(model=>model.MiddleName)
</br>
@Html.TextBoxFor(model=>model.LastName)
Когда отправлено, есть два способа, как я могу получить его на уровне контроллера:
1)
public ActionResult(UserViewModel user)
{
var myUser = new User();
myUser = user.FirstName;
myUser = user.MiddleName;
myUser = user.LastName;
}
а также
2)
public ActionResult(FormCollection collection)
{
var myUser = new User();
myUser = collection.Get("FirstName");
myUser = collection.Get("MiddleName");
myUser = collection.Get("LastName");
}
Вопрос: есть ли причина использовать один метод над другим? Также несколько разработчиков сказали мне, что второй метод предпочтительнее. Передача объекта целиком, как показано в первом примере, не очень хорошая идея. Зачем?
1 ответ
Краткий ответ: оба работают и оба действительны.
Долговременный ответ: я предпочитаю первый,
- его более объектно-ориентированный, чем второй.
- у вас неявно есть волшебные строки во втором подходе. Конечно, вы можете использовать их как внешние, и так далее, но опять же, сильные типы всегда лучше, чем строка за строкой.
- вы определяете свои проверки один раз в варианте 1, вы должны делать это снова и снова в варианте 2.
Вы можете использовать AutoMapper. Он отобразит большинство полей с похожими именами и попросит вас определить остальные. Здесь вам вообще не нужно перемещать поле за полем (см. Ниже). Однако вы должны сделать это один за другим при втором подходе. Это будет выглядеть так, когда вы закончите с отображениями (что тоже тривиально):
public ActionResult(UserViewModel user) { var myUser = Mapper.Map<User, UserViewModel>(user); }
Разве это не красота?
Я действительно не вижу причин, почему вариант 2 предпочтительнее, чем 1... Я думаю, у них есть свои причины. Это как COBOL против C++.:))
Но это действительно индивидуальное решение и стиль. Там нет правильного ответа.
Надеюсь, это поможет.