I've been fiddling with some ASP.NET MVC3 solution structures and I have settled on a design that is made up of the following projects:
MyApp.Web - MVC3 Web Layer
MyApp.Data - Repositories and infrastructure for managing data
MyApp.Domain - POCO Entities
MyApp.Service - Service layer through with I manipulate the model
MyApp.Test - doh
Where would you put your custom validation attribute classes? As far as I'm concerned they should go in the Domain project because they are specific to the entity classes that live there, but then I would need to reference a number of dlls such as System.Web.MVC and I would have liked to have kept references in that project to a bare minimum. Thoughts?
Update:
I removed all attributes from my Domain project and created view models to wrap them in the Web project.
Placed all my custom validation classes in a folder in the web project. Thanks guys
You do not need to reference the web dlls. Only System.ComponentModel.DataAnnotations
Put the validation attributes where they are use.d
Update
Why not? Almost every example I've seen uses POCOs in views. What's the alternative? Creating some kind of wrapper classes for my POCOs?
Because of:
Security
Let's say that you got a User POCO with an IsAdmin
field. By using the POCO, the ModelBinder in MVC will set that property if it's POSTed by a "hacker" who therefore gain admin access.
Isolation
Using the POCO in your view makes your View indirectly dependent of your database. Sure, POCOs are supposed to remove that dependency. But in reality they seldom do.
Customization
You do seldom show all values in a view as they are stored in the db.
The code to adapt a model should not be in the view, but in the viewmodel. Use as little logic as possible in your views.
I would create these attributes on the Web Project and append them to the viewmodel instead of the entity.
I would have DataAnnotation Attributes in your Web Project, preferably in a Common.Attributes folder. I think what jgauffin was getting at (and I'd agree) is that your CustomAttributes should really be decorating ViewModels vs Entities in your Domain project.
I would have followed your original intent of adding the attributes to the Domain objects