MVC,ViewModels和验证

时间:2010-12-31 00:54:11

标签: .net asp.net-mvc-3 poco ef4-code-only

我正在使用POCO创建一个带有EF4的MVC3应用程序。我已经为我的EF实体添加了验证属性。现在,当我构建视图时,我想使用视图模型(也许使用AutoMapper来填充它们)。

我遇到的问题是我必须在我的视图模型上重新定义违反DRY主体的验证属性。例如,如果我决定更改字段的大小,我必须更改POCO和使用它的任何视图模型的MaxLength属性。

是否有一些棘手的方法可以将验证规则从我的POCO映射到我的视图模型?

3 个答案:

答案 0 :(得分:5)

我个人在视图模型中执行验证。这是控制器从视图接收的内容,它是包含用户输入的类。我区分了两种类型的验证规则:表面验证和业务验证。应在视图模型中强制执行必填字段,正确格式等规则,而应在模型上验证数据库中已存在具有给定名称的用户等业务规则。

此外,您可以将不同的视图模型映射到同一模型,但基于视图验证规则可能会有所不同。因此,您不会在视图模型上具有完全相同的验证规则。

答案 1 :(得分:2)

获得抽象的一种方法是让ViewModel'由您的业务模型类组成',包括您需要的其他视图信息。

class MyObject 
{
    public int ID {get;set}

    [Required]
    [StringLength(512)]     
    public string Name {get;set;}

}

class MyViewModel // ViewModel for a specific view 
{
    public MyObject MyModel {get;set;}        // the model that is being edited 

    // other data the view might need, set by the controller 
    public string SomeMessage { get; set; }
    public List<SomeObject> SomeObjects {get;set;} /// e.g. for a drop-down list

}

然后在视图中相应地引用ViewModel。

@model My.Namespace.MyViewModel


Hello @model.MyModel.Name !!!

这样,您只能在一个地方指定商家类中的验证和/或数据注释。

如果您想要进行不同的验证,则需要一些策略来有选择地应用验证逻辑。

答案 2 :(得分:1)

我也很挣扎,我同意它违反DRY。我最近发布了一个关于这个Here的问题并得到了相当多的推迟。

在任何现实世界的应用程序中,你都无法获得完美的DRY。有时你会因违反原则而获得更多好处,而不是盲目地坚持下去。

编辑:

有人可能会认为DRY可能违反单一责任原则(SRP)。通过重用类似的代码,您现在正在使代码执行多个操作。如果您认为数据模型和视图模型具有不同的目的,从而具有不同的职责......将它们组合到单个模型中会违反SRP。也就是说,通过使您的数据模型也成为一个视图模型,这是两个不同的职责。

现在,人们可以想到在这方面可以尝试和协调SRP与DRY的多种方法,但在某些时候你必须权衡成本的好处。