gpt4 book ai didi

asp.net-mvc - 为什么我们使用 ViewModel?

转载 作者:行者123 更新时间:2023-12-03 11:01:16 25 4
gpt4 key购买 nike

我最近开始作为一名网络开发人员工作。我使用 ASP .NET MVC 4 和 NHibernate。

在我的工作场所,我们严格要求使用 View 模型在 Controller 和 View 之间来回传输数据。并且 View 模型不应该包含模型的任何对象。
我知道它是 Controller 和 View 之间的一种层。

但是我发现即使我们可以直接将模型的对象发送到 View (在大多数情况下),编写 View 模型类也是重复和多余的。

例如,如果我想显示订单,我可以在 Controller 的操作中执行此操作 -

return View(Repository.Get<Order>(id));

但相反,我必须编写一个 View 模型,用获取的顺序填充它,然后将其传递给 View 。

所以,我的问题是,当我们可以按原样使用模型的对象时,编写 View 模型的目的是什么?

最佳答案

对于较小的项目,您是对的。我听到你的论点并表示同情 - 然而,这是有充分理由的,繁重和重复的工作,尤其是在更大和更复杂的应用程序中:

  • 必须在 Controller 的操作中执行所有处理。但是在您给出的示例中, Repository.Get 方法可能会返回一个延迟评估的 IQueryable 对象,这意味着在评估 View 之前不会命中数据库。由于各种原因,这很糟糕。 (解决方法是在 Controller 中时调用 .ToList)。
  • “ View 不应包含任何非呈现逻辑”和“您不应信任 View ”(因为 View 可能是用户提供的)。通过提供模型对象(可能仍连接到事件的 DatabaseContext), View 可以对您的数据库进行恶意更改。
  • View 的数据显示并不总是与其模型的数据 1:1 映射,例如考虑用户详细信息页面:

    用户的 EF 模型对象表示其在数据库中的实体,所以它可能看起来像这样: User { UserId, UserName, PasswordHash, PasswordSalt, EmailAddress, CreatedDate } ,而“用户详细信息”页面上的字段将是 User { UserId, UserName, Password, ConfirmYourPassword, EmailAddress } ,你看到区别了吗?因此,您不能使用 EF User 模型作为 View 模型,您必须使用单独的类。
  • 模型操作的危险:如果您让 ASP.NET MVC(或任何其他框架)将模型绑定(bind)到传入的 HTTP POST 请求然后(以上面的用户详细信息示例为例),用户可以通过伪造 UserId 来重置任何人的密码适当的值(value)。 ASP.NET 将在绑定(bind)期间重写该值,除非您专门对其进行清理(这与制作单个 ViewModel 一样繁琐),否则此漏洞将仍然存在。
  • 在有多个开发人员在团队情况下工作的项目中,一切都保持一致很重要。某些页面使用定制的 ViewModel 而其他页面使用 EF 模型并不一致,因为团队没有共同的意识,事情必须记录在案并且通常是有意义的。出于同样的原因,单个开发人员无需在其源代码中放入过多的 XML 文档就可以侥幸逃脱,但在团队情况下,如果您不这样做,您将分崩离析。

  • 在您的情况下,我将与您分享一个轻微的解决方法,但请注意先决条件:
  • 您的意见可以完全信任
  • 您的 View 仅包含表示逻辑
  • 您的应用程序主要是 CRUD
  • 您的 View 与每个 EF 实体模型 1:1 对应(即没有 JOIN)
  • 您的 View 仅处理 POST 表单的单个简单模型,而不是复杂模型(即对象图)

  • ...然后你可以这样做:
  • 将所有单向、非表单相关的数据放入您的 ViewData 集合,或 MVC 4 中的 ViewBag(如果您是铁杆,甚至是通用的 ViewData<T>)。这对于存储 HTML 页面标题和与母版页共享数据很有用。
  • 使用完全评估和加载的 EF 模型作为 View<TModel> 模型。

  • 但是请谨慎使用这种方法,因为它会引入不一致。

    关于asp.net-mvc - 为什么我们使用 ViewModel?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14423056/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com