5

I'm struggling to mesh two best practices together:

  1. Using DataAnnotations + ModelBinding for validation in ASP.NET MVC 2
  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 all DTOs that correspond with that value and update their validation attributes.

3 Answers 3

3

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.

Sign up to request clarification or add additional context in comments.

9 Comments

That seems a bit restrictive. What if one view needs all the properties of an entity while another view only needs a few? Wouldn't that use case call for multiple DTOs?
I agree with Kevin, I could think of instances were I would want multiple DTOs for display purposes. However, only having one DTO for submitting data would be a sensible approach.
DTO's are bags for your data, the ViewModel is the place to mix & match. I don't think it's a good idea to have multiple DTO's with varying data, that gets into the mess you rightly don't want to have to maintain.
Right, I understand the need to mix and match DTOs. Where this breaks down, I think, is when your DTOs contain too much information. For example, if you needed to support two views for displaying a single product entity's information, one for admins and one for normal users. The admin view might require a complex DTO that flattens the product and its relationships while the normal user view might only require a basic DTO with far less information. How would you handle that?
DTO's are storage-independent "flattened" versions of your Model(s). There should be only one DTO per Entity. I would not create a DTO that includes both a product and its related Entities. It is the role of the ViewModel to aggregate related data together to support the needs of a View.
|
3

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.

Comments

1

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.

1 Comment

While, I may be incorrect in saying this, I recommend using Metadata in DTO classes and not outside. as mentioned in my comments above. I would however put them into a metadata type if I was binding directly to my Entity Framework layer on a simple project and/or use the fluent API.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.