2009-07-22 56 views
2

我有一个名为Customer的业务模型,它具有许多必需的属性(通过DataAnnotations)和其他验证规则。何时使用ViewModel而不是Model?

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

我遇到的问题是我想要一个强类型的视图,但我不能在这里使用Customer类型。由于该视图只会编辑地址数据,因此它不会返回Customer对象为验证而需要的其他所需数据。

这表明我应该使用ViewModel。但是,有很多业务规则适用于客户的地址相关属性,我必须在新的ViewModel上重复(地址长度,邮编码,州格式等)。他们需要重复,因为客户端验证(我使用xVal)需要该信息才能正常工作。

我觉得我已经达到了catch-22场景。 DRY告诉我,我不应该在我的Model已经拥有的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 .... 
} 

这为我节省了使用automapper的步骤。

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

+0

你有没有找到一个优雅的解决方案呢? – 2009-08-18 09:33:27

+0

@Andrew - 我用我的解决方案更新了我的问题。不是一条完美的路线,而是我能想到的最好的路线。 – 2009-08-18 14:49:07

回答

1

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

0

从技术角度来看,您的观点应该只与您的ViewModel交流,而不是模型。所以你的viewmodel应该把所有的验证委托给模型。 ViewModel应该添加交互层的东西。

当然,在Silverlight中,这一切都会崩溃,你通常需要在客户端进行一些快速验证,所以突然之间你会将所有验证规则复制到ViewModel。我还没有想出办法。

+0

听起来没有争议,但我认为它非常重要的是要在Web应用程序上对客户端进行验证。为什么要让用户立即修复他们的输入时,往返于服务器?像xVal这样的产品仅用于此目的。 – 2009-07-22 21:44:17

相关问题