我有一个名为Customer的商业模式,它有许多必需的属性(通过DataAnnotations)和其他验证规则。
我有一个View,用于编辑客户的地址字段。
我遇到的问题是我想要一个强类型的视图,但我无法在这里使用Customer类型。由于视图仅编辑地址数据,因此它不会返回Customer对象为验证而需要的任何其他所需数据。
这表明我应该使用ViewModel。但是,有许多业务规则适用于客户的地址相关属性,我必须在新的ViewModel上复制(地址长度,邮政编码,状态格式等)。它们需要重复,因为客户端验证(我正在使用xVal)需要该信息才能运行。
我觉得我已经达到了捕获22的情景。 DRY告诉我,我不应该在我的Model已经拥有的ViewModel上复制我的业务规则,但另一方面我不能使用Model,因为它永远不会验证。
在这种情况下,最佳做法是什么?
所选路径
我最终选择的解决方案是ViewModel路径。为了得到我需要工作的验证,没有其他实用的方法。
然而,使用ViewModel长大后无法消除一些粗糙的斑点。我重构了一些模型,使用包含我知道会在ViewModel中重复使用的属性的接口。由于ViewModels现在可以使用与模型相同的接口,因此它允许我执行以下操作:
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。
答案 0 :(得分:1)
我遇到了同样的问题,复杂的模型类不能很好地处理简单的视图和模型绑定。我也碰巧使用xVal。我遇到的诀窍是使用Validation Buddies覆盖DRY角度以进行基本验证,然后使用AutoMapper将事物推回到完整的模型类中。然后,我可以运行第二轮服务器端验证,以涵盖需要访问数据库的更复杂的位等。
答案 1 :(得分:0)
从技术支持来看,您的观点应该只与您的ViewModel对话,而不是模型。因此,您的viewmodel应该将所有验证委托给模型。 ViewModel应该添加交互层内容。
当然,这一切都在Silverlight中崩溃了,您通常需要在客户端进行某种快速验证,所以突然之间您将所有验证规则复制到ViewModel。我还没有找到解决方法。