Is it possible to use DataAnnotations with Interfaces?

后端 未结 2 1489
青春惊慌失措
青春惊慌失措 2020-12-08 20:25

I want to use DataAnnotations to validate classes that implements some interfaces, and so I\'m adding validation attributes to the interface, like this:

publ         


        
相关标签:
2条回答
  • 2020-12-08 20:48

    If you use a base class instead of an interface, the attributes will work fine.

    0 讨论(0)
  • 2020-12-08 20:55

    I'm surprised no one mentioned MetadataTypeAttribute. But yes, this works.

    [MetadataType(typeof(ICustomerMetaData))]
    public partial class Customer
    {
    }
    
    
    public interface ICustomerMetaData
    {
      // Apply RequiredAttribute
      [Required(ErrorMessage = "Title is required.")]
      string Title { get; }
    }
    

    As for using an Interface directly (using Customer: ICustomerMetaData):

    The product team does not want to implement this feature, for two main reasons:

    • Consistency with DataAnnotations.Validator

    • Consistency with validation behavior in ASP.Net MVC

    • Tricky scenario: a class implements two interfaces that have the same property, but with conflicting attributes on them. Which attribute would take precedence?

    While MVC automatically registers the MetaData with the TypeDescriptor, you may have to manually add it yourself:

      using System;
      using System.Collections.Generic;
      using System.ComponentModel;
      using System.ComponentModel.DataAnnotations;
    
      public class Program
      {
         public static void Main()
         {
            var customer = new Customer();
    
            TypeDescriptor.AddProviderTransparent(
              new AssociatedMetadataTypeTypeDescriptionProvider(typeof(Customer), 
                typeof(ICustomerMetaData)), 
                typeof(Customer));
    
            var context = new ValidationContext(customer);
            var validationResults = new List<ValidationResult>();
    
            var isValid = Validator.TryValidateObject(
              customer, context, validationResults, true);
            Console.WriteLine($"is Valid = {isValid}");
    
            customer.Title = "I has Title";
    
            isValid = Validator.TryValidateObject(
              customer, context, validationResults, true);
            Console.WriteLine($"is Valid = {isValid}");
    
    
            Console.ReadKey();
         }
    
         [MetadataType(typeof(ICustomerMetaData))]
         public partial class Customer
         {
            public string Title { get; set;  }
         }
    
         public interface ICustomerMetaData
         {
            // Apply RequiredAttribute
            [Required(ErrorMessage = "Title is required.")]
            string Title { get; }
         }
      }
    

    Output:

    is Valid = False

    is Valid = True

    0 讨论(0)
提交回复
热议问题