【问题标题】:When to use a ViewModel rather than a Model?何时使用 ViewModel 而不是 Model?
【发布时间】:2009-07-22 21:36:28
【问题描述】:

我有一个名为 Customer 的业务模型,它有许多必需的属性(通过 DataAnnotations)和其他验证规则。

我有一个允许编辑客户地址字段的视图。

我遇到的问题是我想要一个强类型视图,但我无法在此处使用 Customer 类型。由于视图只会编辑地址数据,因此不会返回 Customer 对象验证所需的任何其他必需数据。

这表明我应该使用 ViewModel。但是,有许多业务规则适用于 Customer 上与地址相关的属性,我必须在新的 ViewModel 上复制这些规则(地址长度、邮政编码、状态格式等)。它们需要复制,因为客户端验证(我正在使用 xVal)需要该信息才能运行。

我觉得我已经达到了第 22 条规定。 DRY 告诉我,我不应该在我的模型已经拥有的 ViewModel 上复制我的业务规则,但另一方面我不能使用该模型,因为它永远不会验证。

在这种情况下,最佳做法是什么?

选择的路径

我最终选择的解决方案是 ViewModel 路径。为了获得我需要工作的验证,根本没有其他实用的方法。

但是,使用 ViewModel 提出来的一些粗糙点是无法消除的。我重构了一些模型以使用包含我知道将在 ViewModel 中重用的属性的接口。由于 ViewModel 现在可以使用与模型相同的接口,因此我可以执行以下操作:

 public ActionResult Edit(AddressViewModel address)
 {
      if(!ModelState.IsValid)
          return View();

      var customer = Customer.Load(address.CustomerId);
      UpdateModel<IAddress>(customer);

      // more stuff ....
 }

这省去了我使用自动映射器的步骤。

我在下面选择的答案(由 Wyatt Barnett 提供)我觉得对大多数情况都很好,我在我拥有的其他项目中使用它,特别是对 Linq-to-Sql 有用。

【问题讨论】:

  • 你有没有找到一个优雅的解决方案?
  • @Andrew - 我用我的解决方案更新了我的问题。不是一条完美的路线,但我能想到的最好的路线。

标签: asp.net-mvc mvvm


【解决方案1】:

我遇到了同样的问题,复杂的模型类不能很好地处理简单的视图和模型绑定。我也碰巧在使用 xVal。我遇到的技巧是使用 Validation Buddies 覆盖 DRY 角度以进行基本验证,然后使用 AutoMapper 将事物推回到成熟的模型类中。然后我可以运行第二轮服务器端验证,以涵盖需要访问数据库等的更复杂的位。

【讨论】:

  • 读起来很有趣,在一般意义上非常有用。我不确定这在多大程度上适用于我的案例......我没有使用 Graham 的冻结类,所以我真的不需要该类的 MetadataType 版本。在这一点上创建一个伙伴类只是一个额外的层......本质上是创建一个带有验证的虚拟机。这可能是我唯一的选择,我只是不认为它是“正确的”。不过我会继续考虑。
【解决方案2】:

从技术角度来看,您的视图应该只与您的 ViewModel 对话,而不是与模型对话。因此,您的视图模型应将所有验证委托给模型。 ViewModel 应该添加交互层的东西。

当然,这一切在 Silverlight 中都分崩离析,您通常需要在客户端完成某种快速验证,所以突然之间,无论如何您都要将所有验证规则复制到 ViewModel。我还没有想办法解决这个问题。

【讨论】:

  • 听起来不是很有争议,但我认为在 Web 应用程序的客户端上进行验证非常重要。当您可以让用户立即修复他们的输入时,为什么还要往返于服务器? xVal 之类的产品仅用于此目的。
  • @Sailing Judo - 是的,但我在 ASP.NET 等严格的 Web 应用程序中没有看到太多使用 MVVM。这通常是 MVC。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多