2010-09-19 87 views
9

每次我开始处理新的ASP.NET MVC Web应用程序时,我不确定是否使用DataAnnotations验证。有些事情感觉不对。DataAnnotations或在服务中手动验证?

例如,假设我有一个UserService,它从AccountControllerCreate操作中通过CreateUserModel。为确保用户始终提供名称,我将模型的Name属性设置为具有[Required]属性。我现在是安全的,除非它有一个名字,否则模型联编程序永远不会给我一个CreateUserModel

我的问题是,我的UserService是我系统的一个可重用组件,它不能依赖上述层提供有效数据的事实,而且肯定也必须验证此数据。当您考虑您可能要编写一个完全重用UserService(并且没有模型联编程序为其进行所有数据注释验证)的Web服务时,需要进一步突出显示这一点。

所以我的问题是:这种情况的最佳做法是什么?使用数据注释进行验证并在服务中重复验证?仅在服务中验证并抛出异常?两者的混合?

我希望我的问题不是太主观,我主要试图建立一个关于是否将验证移动到数据注释最终会让我最终咬伤我的共识。

回答

1

你是对的,你应该关闭控制器验证并在服务层验证。如果您愿意,您仍然可以使用DataAnnotations。服务层可以使用验证消息抛出异常,控制器可以捕获该异常并将验证消息添加到ModelState中。您可以通过处理控制器的OnException方法上的验证异常来避免为每个操作执行此操作。

1

只要逻辑是在一个地方定义的,我个人并不介意事物会被验证两次,这在您的情况中显然是这样。我对MVC的描述经验不足,但我可以想象,从服务层抛出异常并不会给用户体验(UX)带来与MVC在验证时可以提供的一样好的用户体验(UX)实例在无效的文本框旁边显示一条错误消息,当从服务层抛出异常时更难做到这一点)。当用户体验相同时,请仅在服务中进行验证,否则在两个层次都进行验证。

6

我在服务层执行所有的验证,使用手动验证(如果x == y)和使用数据注释的组合。

要在服务层中使用数据注释,您必须使用TryValidateObject()方法手动使用Validator类。一个很好的例子可以看到here

然后,您必须将验证错误从服务层传递到您的控制器,并让您的控制器将每个错误添加到模型状态错误列表中。

+1

这就是我们所做的,除了我们将IValidationDictionary传递给作为ModelState包装器实现的服务层,以便服务层能够直接向ModelState添加错误,但不会依赖于ASP.NET MVC。然后控制器不需要担心管理向ModelState添加返回的错误。 – 2010-11-24 21:16:50