views:

139

answers:

6

As I'm learning more and more about ASP.NET MVC the more I am introduced to Data Annotations.
Specifically in MVC they are used for validation and this gives me some concerns.
The biggest is due to the fact that I like to keep my model as POCOs and as clean as possible.
Now what if I have those model classes shared across multiple projects in a solution (i.e. web front end, desktop app, web services)?
Basically I am concerned that annotations specific for my MVC front end app could influence some other projects like Dynamic Data, etc. I already have my Business Objects separated from my database model (in this case LINQ2SQL) so I don't worry about annotations having influence on my DAL, but I'm wondering if my fear about other projects is legitimate.

Also I think that tying a required error message to your model is a bit insane.

I suppose the problem would be solved if I created separate models for each project (web, desktop, web service, etc.) but this would be practically a direct copy of my currently shared model. Is it the right path?
It would have big impact on my solution (much mapping from one model to another happening).

What do you think?
I would like to hear what you consider good and bad use of Data Annotations.

A: 

Really, really good question. Especially since all the shiny demo example apps are built around DataAnnotations handling all the validation because its such a nice, shiny selling point. And who likes doing validation anyhow?

I think the better way to look at this is that they should be part of a fuller validation solution, both for the structural reasons you mention as well as their limitations -- how do you validate stuff like "Is this user name unique?" or "Is this manager allowed to assign this task to this employee?" using data annotations?

Wyatt Barnett
+1  A: 

DataAnnotations isn't the only method available for validation and you can use more than one validation method. Most validations I've seen when using DataAnnotations are specifically for validating the data that will go in the database. Such as MaxLength() and Range().

IValidatableObject is the most flexible that I've seen when it comes to writing your own validations. However, it doesn't help your specific example of having a single repository that would hold all your objects. But no fear!

IDataErrorInfo is another way you can validate data and this one can be used in your MVC app alone and it wouldn't affect other projects.

If a class implements the IDataErrorInfo interface, the ASP.NET MVC framework will use this interface when creating an instance of the class. Thus you can separate your validation using a service locator interface or something similar.

I find IValidatableObject to be a better implementation, however.

BuildStarted
A: 

Not sure if DataAnnotations will mess up your other projects, but it's expected them will ignore DataAnotations unless you create some classes to check them.

About keeping your POCO as simple as possible, DataAnnotations' intention is to keep metadata and data at the same place (i.e. if it's required that _UnitsInStock must always be a positive integer, somehow this requirement is related to the data definition of "units in stock" and fits perfectly the definition of model). It also helps avoiding some mistakes, since that no matters where you are using validation (inside a mvc project) the rules will always be the same (so you can't forget to check a variable for a minimum value in page A while you check it in page B). The error messages are not required, but you can use it to show a more friendly message, and this error message will be shown everywhere.

It also makes very easy to implement automated server and client validation (mvc).

In other hand, despite you have the ability to create custom attributes to check business rules, it requires more knowledge and patience than using a "business class" (if you're not used to it), and as far as i know, it's only officially supported by mvc 2.

If your model classes are shared among other projects, probably you also have a shared validation layer, so use this validation layer instead. If you don't have it, so DataAnnotations will make your life easier on MVC projects.

Gmoliv
+1  A: 

I personally find DataAnnotations very nice for the validation of MVC ViewModels and posted input. I would never ever ever ever put them on my business models.

I've also become quite partial to attribute based validation attributes because its really easy to get into Reflection to discover what attributes are where.

jfar
+1  A: 

I find Data Annotations convenient for models where the rules never change depending on context such as an email address.

But for more complex validation (multiple fields, requires DB access, etc.) I use the visitor pattern described in Entity validation with visitors and extension methods.

Todd Smith
A: 

I don't think you need to worry about sharing a decorated domain in multiple technologies. DataAnnotations is part of the BCL and you can use it in WCF, WPF, MVC, Web Forms, you name it (perhaps even in Silverlight).

Because DataAnnotations is now a core part of the BCL we can expect other validation frameworks to be able to read those attributes in the future, as Enterprise Library Validation Application Block 5.0 already does. This allows extending the model with more complex validations later on, without having you change the core validation rules.

However, I can understand you want to keep your model and the validation rules separate. If this is what you want, Validation Application Block (VAB) can be a good alternative (or even addition, because of its integration with DataAnnotations). VAB supports configuration-based validation, which allows you to completely separate the validation rules from the model.

When your validation rules are very simple however, VAB can be an overkill. It is extremely powerful and extendable, but it is also complex and time consuming to learn.

Steven