views:

66

answers:

3

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, let'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.

A: 

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.

Max Toro
A: 

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.

Steven
+1  A: 

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.

KallDrexx