SOfanatic
SOfanatic

Reputation: 5573

how to synchronize data annotations between model and view models

I'm working with EF Code First, so my data annotations are driving my SQL server database columns definitions/properties (i.e., [StringLength(30)] = nvarchar(30), etc.). I'm using ViewModels to drive my views. How can I synchronize the data annotations between Models and ViewModels?

For example, I have the following entity class:

public class Ticket
{
    ...
    [Required]
    [DataType(DataType.Currency)]
    [DisplayFormat(DataFormatString = "{0:C}")]
    public double TicketBalance { get; set; }
    ...
}

And a ViewModel that uses the same property from the Model class:

public class EditTicketViewModel
{
    ...
    [Required]
    [DataType(DataType.Currency)]
    [DisplayFormat(DataFormatString = "{0:C}")]
    public double TicketBalance { get; set; }
    ...
}

How can I synchronize these two data annotations?

Upvotes: 4

Views: 1030

Answers (2)

Yellowfog
Yellowfog

Reputation: 2343

While you can't change the attributes on your ViewModels at runtime, you can to some degree emulate them for the purposes of validation (which is presumably the reason that you're using data annotations).

This requires creating the ViewModels using an object mapper like AutoMapper or EmitMapper. You can then hook into an appropriate part of the mapping process to update the DataAnnotationsModelMetadataProvider and DataAnnotationsModelValidatorProvider, which are used by MVC in the various parts of the validation process.

This answer shows a way of doing it with AutoMapper. I'm currently having some fun looking at a solution with EmitMapper, since that's somewhat faster to execute.

Upvotes: 2

Display Name
Display Name

Reputation: 4732

There is no synchronization between the two. While they may look similar, they actually are different: one is for the database, another is for the GUI.

  • For the database you mainly want to test for [Required] and [StringLength(XXX)]. Sometimes [DataType] as well.

  • For the GUI you want to check for those in addition of formatting, regular expressions, ranges etc.

There are validation attributes, display attributes, data modeling attributes. Choose the right attributes category at the right place according to the situation.

And it gets even worse when you start using things like jQuery validation or KnockoutJS validation. In that case you will have to duplicate your efforts third time for JS purposes. Unfortunately.

You can also check what other folks did here: How do I remain DRY with asp.net mvc view models & data annotation attributes?

There folks use inheritance. which is fine, but a bit confusing while you let others read your code later on.

The good advise is to switch from data annotations to fluent validation as per one of the responses in the link above. It will allow you to apply the same validation class to multiple models.

Hope this helps.

Upvotes: 1

Related Questions