MVC3 服务层验证。返回异常、自定义对象、模型状态字典?
只是对您关于服务层验证的想法或经验感到好奇。
我必须处理相当标准的验证,例如“具有名称属性的对象尚不存在”,但我不确定如何将这些验证失败返回到控制器。
我最初的想法是实现一个标准的 List
但我已经看到了它的每一种方式,所以很好奇每种方式的优缺点。
感谢您的任何意见。
Just curious on your thoughts or experiences around service layer validation.
I have to process fairly standard validation such as "object with name property doesn't already exist", but I wasn't sure how to return these validation failures back to the controller.
My initial thought was to implement a standard List<ValidationError>
but I've seen it done each and every way so was curious the pros/cons of each.
Thanks for any input.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您使用 System.ComponentModel.DataAnnotations 条目,您可以(正如您似乎知道的那样)用必需的和更多标签来装饰您的属性,
尽管我个人使用 ViewModels 而不是将域 mdoels 暴露给视图,您的控制器操作现在可以执行类似的操作:
这是 MVC 中标准“后”处理程序模式之一。在我看来,这是验证对象模型的最简单途径。
从那里,还有一些其他选项 - 您的域对象可以实现 IValidatedableObject 并且您可以
yield return
错误(请参阅http://buildstarted.com/2010/09/20/mvc-3s-ivalidatableobject/ 作为 例子)。不过,我建议不要混合两者,就好像您正在使用数据注释并且甚至有一个无效属性一样,将不会调用 IValidatableObject 上的 IsValid 方法。
从那里,您可以使用自定义验证属性做很多事情(IsValid 的扩展版本似乎为您提供了更大的灵活性http://msdn.microsoft.com/en-us/library/gg480674%28v=vs.98%29.aspx)
希望上述内容对您有所帮助 - 一旦您通过了基础知识你可以用它做很多事情,比如自定义属性的客户端验证等都很有趣。
干杯,
Terry
[编辑添加:
重新阅读您的帖子后,您可能只想在服务层进行验证?如果是这样,我使用了以下方法:
显然您的 Name 属性需要
{ get;私人套装;为此,尽管您始终可以将 Validator.ValidateProperty 添加到公共属性的扩展设置器中。
]
If you go with System.ComponentModel.DataAnnotations entries you can (as you seem to know) decorate your properties with required and many more tags
although I personally use ViewModels rather than exposing domain mdoels to the view, your controller action can now do something like:
This is one of the standard 'post' handler patterns in MVC. This is the simplest path to getting your object model validating in my opinion.
From there, there are a few other options - your domain object can implement IValidatedableObject and you can
yield return
the errors (see http://buildstarted.com/2010/09/20/mvc-3s-ivalidatableobject/ as an example).I'd recommend not mixing the two though, as if you are using dataannotations and have even a single invalid property, the IsValid method on IValidatableObject will not be called.
From there, there's lots you can do with custom validation attributes (the extended version of IsValid seems to give you more flexibility http://msdn.microsoft.com/en-us/library/gg480674%28v=vs.98%29.aspx)
Hope some of the above helps - once you get past the basics there's a lot you can do with it and things like client validation of custom attributes etc. are all fun.
Cheers,
Terry
[edit to add:
After re-reading your post, it may be that you want to only validate at the service layer? If so, I've used the following approach:
obviously your Name property would need a
{ get; private set; }
for this, though you could always add the Validator.ValidateProperty into an extended setter for the public property either.]
在我正在开发的一个新项目(第一次使用 mvc)中,我一直在使用 ms code 合约(它会引发异常)并对我的域对象本身进行所有验证。对于无法在那里验证的事情(例如需要数据库访问的验证),我在我的服务中进行验证并抛出异常。另外,就像上面的海报一样,我对所有带有数据注释验证器的所有内容都有完整独立的视图模型。异常冒出来,我在控制器中捕获它们并将其附加到 ModelState。这些和视图模型验证有很多重叠,但不需要太多额外的工作,并且允许我改变每个视图的验证,但仍然需要“核心”验证。
《pro asp mvc 2》这本书有另一个很好的方法——编写一个继承Exception并包含错误集合的类。然后你进行验证,添加到集合中,然后抛出异常,然后他在控制器中捕获它并复制到 ModelState。此方法将让您捕获一个异常中的所有错误,而不仅仅是服务层的一个错误。
On a new project I'm working on (first time mvc) I've been using the ms code contracts (which throw exceptions) and do all the validation on my domain objects themselves. For things that can't be validated there (such as validations that require database access) I validate in my services and throw exceptions. Additionally like the poster above I have whole separate view models for everything that have data annotations validators on them. The exceptions bubble up and I catch them in the controller and append to the ModelState. There's a lot of overlap with those and the view model validation but it's not much extra effort and allows me to vary the validation per view and yet still have the "core" validations be required.
The book pro asp mvc 2 has another nice way - write a class that inherits Exception and contains a collection of errors. Then you do your validations, add to the collection then throw the exception then he catches it in the controller and copies over to ModelState. This method will let you catch ALL the errors in one exception instead of just one at the service layer.