Anders Gulbæk
Anders Gulbæk

Reputation: 369

Custom Data Annotations inheritance for reusablity

Say you have a class with an property for Email, with some Data Annotations

public class Person
{
    [Display(Name = "Email address")]
    [Required(ErrorMessage = "The email address is required")]
    [EmailAddress(ErrorMessage = "Invalid Email Address")]
    [CustomDataAnnotation()]
    public string Email { get; set; }
}

Now you need another class with an Email property with the same Data Annotations

public class Invoice
    {
        [Display(Name = "Email address")]
        [Required(ErrorMessage = "The email address is required")]
        [EmailAddress(ErrorMessage = "Invalid Email Address")]
        [CustomDataAnnotation()]
        public string Email { get; set; }
    }

Is there a way to create a new Data Annotation [MyEmail] that inherits all the other Data Annotations? Something like this

    [Display(Name = "Email address")]
    [Required(ErrorMessage = "The email address is required")]
    [EmailAddress(ErrorMessage = "Invalid Email Address")]
    [CustomDataAnnotation()]
    public DataAnnoation MyEmail {get;set;}

And then be able to reuse it like this.

public class Person
    {
        [MyEmail]
        public string Email { get; set; }
    }

public class Invoice
    {
        [MyEmail]
        public string Email { get; set; }
    }

I know its possible to use an abstract class, but I don't like hidding the Email Property in another class making it harder to read.

public abstract class MyEmail
{
    [Display(Name = "Email address")]
    [Required(ErrorMessage = "The email address is required")]
    [EmailAddress(ErrorMessage = "Invalid Email Address")]
    [CustomDataAnnotation()]
    public string Email { get; set; }
}

public class Person : MyEmail {}
public class Invoice : MyEmail { }

Any suggestings for making the Data Annotations more reusable is appreciated.

Upvotes: 0

Views: 771

Answers (1)

hasan
hasan

Reputation: 3502

You can use [MetadataType] attribute on top of your Person and Invoice class to use your MyEmail class data.annatotaions attributes. You can implement like following.

[MetadataType(typeof(MyEmail))]
public class Person
{
    public string Email { get; set; }
}

[MetadataType(typeof(MyEmail))]
public class Invoice
{
    public string Email { get; set; }
}

public abstract class MyEmail
{
    [Display(Name = "Email address")]
    [Required(ErrorMessage = "The email address is required")]
    [EmailAddress(ErrorMessage = "Invalid Email Address")]
    [CustomDataAnnotation()]
    public string Email { get; set; }
}

Upvotes: 3

Related Questions