DataAnnotations or validate manually in services?
Each time I start working on a new ASP.NET MVC web application, I'm not sure whether or not to use DataAnnotations
validation. Something about it feels wrong.
For example, l开发者_高级运维et's say I have a UserService
which is passed a CreateUserModel
from the Create
action of the AccountController
. To ensure the user always supplies a name, I set the model's Name
property to have the [Required]
attribute. I'm now safe in the knowledge that the model binder won't ever give me a CreateUserModel
unless it has a name.
My problem is that for my UserService
to be a reusable component of my system, it can't rely on the fact the layer above is supplying valid data, and surely must also validate this data. The need for this is highlighted further when you consider that you may want to write a web service that fully reuses the UserService
(and wouldn't have the model binder to do all the data annotation validation for it).
So my question is: What is the best practice for this situation? Validate with data annotations and repeat that validation in the services? Validate only in the services and throw exceptions? A mix of both?
I hope my question isn't too subjective, I'm mainly trying to establish a consensus on whether moving the validation to data annotations is going to end up biting me in the end.
I perform all my validation in the service layer, using a combination of manual validations (if x == y) and using Data Annotations.
To use Data Annotations in your service layer, you have to manually use the Validator class using the TryValidateObject()
method. A good example of this can be seen here.
You then have to pass your validation errors down from your service layer to your controller, and have your controller add each error to the Model state error list.
You are right, you should disable the validation on the controller and validate in the service layer. You can still use DataAnnotations if you want to. The service layer can throw an exception with the validation messages, the controller can catch that exception and add the validation messages to the ModelState. You can avoid doing that for each action by handling the validation exception on the OnException method of the controller.
I would personally don't mind that things are validated twice, as long as the logic is defined in one single place, which is clearly the case in your situation. I'm not experienced enough to say much about MVC, but I can imagine that throwing exceptions from the service layer just won't give a user experience (UX) that is as good as what MVC can give you when validating (it can for instance show an error message next to the textbox that is invalid. It is much harder to do that when throwing exceptions from your service layer). When the UX is the same, do your validation only in the service, otherwise do it in both layers.
精彩评论