ASP.NET MVC 2 validation using DTOs instead of domain entities
I'm struggling to mesh two best practices together:
- Using DataAnnotations + ModelBinding for validation in ASP.NET MVC 2
- Using DTOs instead of domain entities when passing data via the ViewModel
If I want to pass over DTOs instead of domain entities, then leveraging DataAnnotations + ModelBinding for validation would require me to specify validation attributes on my DTO classes. This results in a lot of duplicated work since multiple DTOs may hold overlapping fields with the same validation restrictions. This means that any time I change a validation rule in my domain, I have to go find a开发者_JAVA技巧ll DTOs that correspond with that value and update their validation attributes.
You shouldn't have more than one DTO per entity, so you should only have to apply the validation attributes once per DTO. If you need multiple entities for a View, include multiple DTO's as properties of your ViewModel.
You might find useful this.
And keep in mind that validation lives everywhere. There is nothing wrong if DTOs applies UI validation (like getting necessary fields filled, datetime in correct format etc.) and domain objects - domain validation (e.g. account has money before withdrawn operation).
You can't create validation universal. Best thing You can do - put it in appropriate places.
And weed that feeling about duplication out. Usage of DTOs usually means applying single responsibility principle. There is no duplication if you got 2 customer objects where one is responsible for carrying business logic and second that is responsible for displaying it.
Maybe you could use meta annotations, which puts the attributes on a separate class:
namespace MvcApplication1.Models
{
[MetadataType(typeof(MovieMetaData))]
public partial class Movie
{
}
public class MovieMetaData
{
[Required]
public object Title { get; set; }
[Required]
[StringLength(5)]
public object Director { get; set; }
[DisplayName("Date Released")]
[Required]
public object DateReleased { get; set; }
}
}
Code sample was borrowed from this article.
精彩评论