views:

44

answers:

2

So I have been using data annotations for my validation in an MVC project and they seem to work in most scenarios.

Here are two examples in my current project where they don't seem to fit and I am unsure of the best place to put the validation.

1) I have a Join League page that contains a form where the logged in user enters their team name and clicks to join the league. When they submit the form i need to make sure that the current user doesn't already have a team in the league. So it basically needs to query the db for that user id and league id to make sure no team exists for the user. My ViewModel does not contain user id, since it is not relevant to the view.

2) On this same page, I also need to make sure the team name is unique. This is easy if you are just looking to see if it exists in a table. You create a custom validation attribute that query's a table for the value of the field. However i need to see if it exists in a table for a certain league id. (the league they are joining.)

It doesn't seem like Data Annotations are an ideal solution for anything other then trivial validation. My current solution is to query the db at beginning of post action method, and add the error to the ModelState manually. (yes, terrible)

Any ideas?

+2  A: 

I think it may help to put some thought into the difference between Input Validation and Business Logic. Ayende has some thoughts on this here

Rules like 'When they submit the form I need to make sure that the current user doesn't already have a team in the league' sounds like Business Logic, not Input Validation, and you may want to handle it in a different way. This logic could, for instance, go into a 'CanSave' method on a 'User' class or something similar - the key thing is to separate this from Input Validation if you can.

Steve Willcock
Thanks for your insight, I think you are right. :)
Aros
+1  A: 

Although I agree with Steve, DataAnnotations has a base ValidationAttribute in which you can implement anything you want. To say it can only do trivial things is not accurate in fact with this extensibility point you can do almost anything you want.

Now there are some issues with service location being all over the place by having database logic inside your code but there are options to clean this up. The DataAnnotations are applied via a ModelValidatorProvider class that can easily be configured just like you would do ControllerFactories or ViewEngines.

ModelValidatorProviders.Providers.Add(new YourCustomProvider());

Now what you can do in this case is have your validator provider provide the persistence layer code into your attribute. So the code stays clean yet you can use custom data annotation attributes that touch the db.

jfar