Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework 6 Reusing Data Annotations

I've looked for a while for a definitive solution to this but have yet to come to a conclusion. I would like to specify data annotations just once on the data model class and have these be seen by the UI from a view model class without specifying them again. To illustrate my point suppose I have a UserAccount Class as such...

public class UserAccount
{
    [Display(Name = "Username", Prompt = "Login As"), Required()]
    string UserName { get; set; }
    [Display(Name = "Password", Prompt = "Password"), Required(), DataType(DataType.Password), StringLength(255, MinimumLength = 7, ErrorMessage = "The password must be at least 7 characters")]
    string Password { get; set; }
}

now I would like to specify a View Model which contains a password confirmation field that wouldn't be stored in the database and potentially other data models but I don't want to have to specify all the data annotation attributes again. This is about trying to find best practice, but also multiple declarations need maintaining and at some point one will get modified and the others won't.

I've looked at an Interfaces/Inheritance solution but that doesn't really cut it fully for various reasons. One other potential solution might be to have an Attribute on the View Model class (or properties) to say inherit attributes from... but I can't find anything suitable as yet for this.

Has anyone got any bright ideas or implemented this in a suitable fashion?

like image 473
Hoots Avatar asked Feb 13 '23 02:02

Hoots


1 Answers

You can decorate your viewmodel class with this atttribute:

[MetadataType(typeof(YourModelClass))]
public class YourViewModelClass
{
   // ...
}

Assuming that both classes have the same properties, the annotations will be correctly inhertied.

See: MetadataTypeAttribute Class in MSDN for more info.

Note: in MDSN remarks they explain the use for adding extra metadata for an existing model class, but this will work for your case. In fact, you can do it all the way round: annotate your ViewModel, and apply it to a partial class of your model. Or even create a single buddy class which is applied to both the entity in the model and the viewmodel. With any of this options, any class can "define" its own annotations and "inherit" others from the buddy class.

IMPORTANT NOTE: this solution is very different from the accepted one by Hoots in the sense that this solution is recognized by frameworks like EF or MVC, to create the model or to provide automatic data validation. The solution by Hoots must be used by hand, because the framework doesn't automatically use it.

like image 178
JotaBe Avatar answered Feb 16 '23 02:02

JotaBe