Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/magento/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 何时使用ViewModel而不是模型?_Asp.net Mvc_Mvvm - Fatal编程技术网

Asp.net mvc 何时使用ViewModel而不是模型?

Asp.net mvc 何时使用ViewModel而不是模型?,asp.net-mvc,mvvm,Asp.net Mvc,Mvvm,我有一个名为Customer的业务模型,它有许多必需的属性(通过DataAnnotation)和其他验证规则 我有一个视图,可以编辑客户的地址字段 我的问题是我想要一个强类型视图,但我不能在这里使用客户类型。由于视图将只编辑地址数据,因此不会返回客户对象验证所需的任何其他数据 这建议我应该使用ViewModel。但是,有许多业务规则适用于Customer上与地址相关的属性,我必须在新的ViewModel上复制这些属性(地址长度、zipcodes、状态格式等)。它们需要复制,因为客户端验证(我使用

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

我有一个视图,可以编辑客户的地址字段

我的问题是我想要一个强类型视图,但我不能在这里使用客户类型。由于视图将只编辑地址数据,因此不会返回客户对象验证所需的任何其他数据

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

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

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

所选路径

我最终选择的解决方案是ViewModel路径。为了得到我需要的验证,根本没有其他可行的方法

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

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

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

      // more stuff ....
 }
公共操作结果编辑(AddressViewModel地址) { 如果(!ModelState.IsValid) 返回视图(); var customer=customer.Load(address.CustomerId); 更新模型(客户); //更多的东西。。。。 } 这节省了我使用自动制版机的步骤


我在下面选择的答案(由Wyatt Barnett提供)在大多数情况下都很好,我在其他项目中也使用了它,特别是在Linq to Sql中。从技术角度来看,您的视图应该只与您的ViewModel对话,而不是与模型对话。因此,viewmodel应该将所有验证委托给模型。ViewModel应该添加交互层内容


当然,在Silverlight中,这一切都会分崩离析,您通常需要在客户端进行某种快速验证,因此突然之间,您将所有验证规则复制到ViewModel中。我还没有找到解决这个问题的方法。

我遇到了同样的问题,复杂的模型类不能很好地处理更简单的视图和模型绑定。我还碰巧使用了xVal。我遇到的诀窍是使用覆盖基本验证的干燥角度,然后使用AutoMapper将内容推回到完整的模型类中。然后,我可以运行第二轮服务器端验证,以涵盖需要访问数据库等更复杂的部分。

听起来不太好辩,但我认为在web应用程序的客户端上进行验证非常重要。当您可以让用户立即修复其输入时,为什么会导致到服务器的往返?像xVal这样的产品就是为了这个目的而存在的。@Sailing Judo-true,但我还没有看到MVVM在ASP.NET这样的严格的web应用程序上有多少用途。这通常是MVC。阅读起来很有趣,一般来说非常有用。我不确定这在多大程度上适用于我的案件。。。我没有使用Graham意义上的冻结类,所以我并不真正需要类的MetadataType版本。在这一点上创建一个buddy类只是一个额外的层。。。本质上是通过验证创建一个VM。这可能是我唯一的选择,我只是不认为这是“正确的”。不过我会继续思考这个问题。你有没有找到一个优雅的解决方案?@Andrew-我用我的解决方案更新了我的问题。这不是一条完美的路线,但却是我能想到的最好的路线。