Привязка модели в контроллере при публикации формы - зачем использовать модель представления вместо класса из модели предметной области? - PullRequest
2 голосов
/ 25 января 2012

Я все еще довольно новичок в ASP.NET MVC 3. Я сталкивался с моделями представления и их использованием для передачи данных из контроллера в представление. В моем недавнем вопросе о привязке модели два эксперта предложили мне также использовать модели представления для привязки модели.

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

Вот пример ситуации: у меня есть простой класс в моей модели предметной области.

public class TestParent
{
    public int TestParentID { get; set; }
    public string Name { get; set; }
    public string Comment { get; set; }
}

А это мой контроллер:

public class TestController : Controller
{
    private EFDbTestParentRepository testParentRepository = new EFDbTestParentRepository();
    private EFDbTestChildRepository testChildRepository = new EFDbTestChildRepository();

    public ActionResult ListParents()
    {
        return View(testParentRepository.TestParents);
    }

    public ViewResult EditParent(int testParentID)
    {
        return View(testParentRepository.TestParents.First(tp => tp.TestParentID == testParentID));
    }

    [HttpPost]
    public ActionResult EditParent(TestParent testParent)
    {
        if (ModelState.IsValid)
        {
            testParentRepository.SaveTestParent(testParent);
            TempData["message"] = string.Format("Changes to test parents have been saved: {0} (ID = {1})",
                                                        testParent.Name,
                                                        testParent.TestParentID);
            return RedirectToAction("ListParents");
        }
        // something wrong with the data values
        return View(testParent);
    }
}

Итак, в третьем методе действия, который вызывается при получении HTTP POST, я использовал TestParent для привязки модели. Это было довольно удобно, поскольку страница браузера, которая генерирует запрос HTTP POST, содержит поля ввода для всех свойств TestParent. И я действительно думал, что так работают шаблоны, которые Visual Studio предоставляет для операций CRUD.

Однако я получил рекомендацию о том, что подпись третьего метода действия должна выглядеть следующим образом: public ActionResult EditParent(TestParentViewModel viewModel).

1 Ответ

4 голосов
/ 25 января 2012

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

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

  • Случай 2- По мере усложнения ваших входных данных вы столкнетесь с тем, что вам нужно будет отправлять и проверять поля не непосредственно в модели предметной области (флажки «Я согласен» и т. Д.)

  • Случай3 - Более личная вещь, но я считаю, что привязка модели к объектам реляционных доменов порой вызывает огромную боль.Проще связать их в AutoMapper, чем иметь дело с привязкой модели MVC для сложных графов объектов.Html-помощники MVC также работают более гладко против примитивных типов, чем глубокие реляционные модели.

Недостатки использования ViewModels в том, что он не очень СУХОЙ.

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

...