【问题标题】:Model binding in controller when form is posted - why to use view model instead of class from domain model?发布表单时控制器中的模型绑定 - 为什么使用视图模型而不是域模型中的类?
【发布时间】:2012-01-24 21:55:24
【问题描述】:

我对 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)

【问题讨论】:

  • IMO,使用视图模型或模型取决于具体情况。如果页面仅使用特定模型的属性,那么我认为可以将视图强输入到该模型并继续。但是,如果有一些元素本身不是模型的一部分,那么这就是视图模型发挥作用的地方。创建视图模型只是为了将模型表示为视图类型,这违背了 DRY 代码的概念。这是其中一个概念,如果您询问 10 位开发人员,您将得到 12 个答案。底线是使用模型不会(据我所知)违反 MVC 的概念。

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


【解决方案1】:

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

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

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

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

使用 ViewModel 的缺点是它不是很干燥。

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

【讨论】:

  • ViewModel 非常适合 DRY,因为 DRY 通常适用于实际逻辑。 Viewmodels,通常是属性,仅此而已 - 即使看起来它也不要违反 DRY。如果真的担心属性重复,请为共享属性使用共享库,但应该有充分的理由。
猜你喜欢
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-19
  • 1970-01-01
  • 1970-01-01
  • 2015-10-29
  • 2010-11-26
相关资源
最近更新 更多