在ASP.NET MVC中验证ViewModel

Jon*_*han 19 validation asp.net-mvc viewmodel

关于如何在ASP.NET MVC中实现验证的大多数技巧似乎都围绕模型(在模型和控制器之间构建服务层或使用验证属性装饰模型的属性).

在我的应用程序中,我使用ViewModels进行控制器和视图之间的所有通信.

我的登录页面有一个名为"LoginViewModel"的ViewModel,其中包含一个名为"EmailAddress"的属性.

当用户输入其电子邮件地址并单击"提交"时,将填充此ViewModel并将其发送到控制器,在该控制器中验证电子邮件地址.

它必须是有效的电子邮件地址,并且用户必须来自在系统中注册的域.

为此添加验证的便捷方法是什么?我应该将验证放在ViewModel本身吗?还是应该留在控制器中?

kei*_*thm 5

"我应该将验证放在ViewModel本身吗?或者它应该留在控制器中"我同意Robert的意见,但我会添加一个插件以实现额外的自动化.

如果查看xVal等工具,可以看到例程验证(例如,必填字段,范围内的数字,与正则表达式匹配的字符串)可以通过装饰数据类的字段自动完成.事实上,xVal可以自动编写用于例行验证的JavaScript,以便在客户端执行.所有没有编写任何代码.更深入的验证(例如,此用户是在我们的数据库中注册的域的成员吗?)在模型层本身内部发生在服务器端.

使用ViewModel习惯用法可能会给这个方案带来一些挑战.我目前的方法是将我的实体对象嵌入到我的视图模型中,例如

public class Contact {
    [Required]
    string Name { get; set; }
}

public class ContactView {
    public Contact Contact { get; set; }
    public string SomeOtherViewProperty { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后在控制器中,更新模型时会发生浅层验证:

UpdateModel(contactViewModel.Contact, "Contact");
Run Code Online (Sandbox Code Playgroud)

并且需要更多信息或更复杂计算的验证发生在模型层本身内部.

另一种方法是不嵌入实体对象,而只是在两者之间映射单个字段.我最近发现了一个名为AutoMapper的工具,它自动链接域和视图模型对象之间的字段.看起来它应该支持这种验证方法,尽管我还没有使用它.