在发布表单时在控制器中进行模型绑定 - 为什么要使用视图模型而不是域模型中的类?

时间:2012-01-24 21:55:24

标签: asp.net-mvc-3 viewmodel model-binding

我仍然是ASP.NET MVC 3的新手。我遇到了视图模型及其用于将数据从控制器传递到视图的用途。在我最近的question on model binding两位专家建议我也应该使用视图模型进行模型绑定。

这是我之前没有遇到的事情。但是两个人都向我保证这是最好的做法。有人可能会对视图模型更适合模型绑定的原因有所了解吗?

以下是一个示例情况:我的域模型中有一个简单的类。

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 个答案:

答案 0 :(得分:4)

一开始听起来很吸引人,但随着模型和视图操作变得越来越复杂,您开始看到使用ViewModels(大多数)所有内容的价值,尤其是输入场景。

  • 案例1 - 大多数Web框架都容易被过度发布。如果您直接绑定到您的域模型,则很有可能过度发布数据并恶意更改不属于该用户的内容。我发现绑定到输入视图模型比使用白名单或黑名单的长字符串列表更清晰,尽管还有一些其他有趣的方法可以绑定到接口。

  • 案例2 - 随着您的输入变得越来越复杂,当您需要提交和验证不直接在域模型中的字段时(“我同意”复选框等)

    < / LI>
  • 案例3 - 更多的个人事物,但我发现模型绑定到关系域对象有时是一个巨大的痛苦。在AutoMapper中更容易将它们链接起来,而不是处理复杂对象图的MVC模型绑定器。与深层关系模型相比,MVC的html帮助程序对原始类型的工作也更加顺畅。

使用ViewModels的不利之处在于它不是很干。

故事的寓意是,绑定到域模型可以成为简单事物的可行解决方案,但随着复杂性的增加,拥有一个单独的视图模型然后在两者之间进行映射变得更容易。