【问题标题】:Is it possible to use DataAnnotations with Interfaces?是否可以将 DataAnnotations 与接口一起使用?
【发布时间】:2011-05-07 06:44:16
【问题描述】:

我想使用 DataAnnotations 来验证实现了某些接口的类,因此我正在向接口添加验证属性,如下所示:

public interface IUser
{
    [Required]
    string Name { get; set; }

    [Display(Name = "Email Address")]
    [Required]
    string Email { get; set; }
}

当我尝试使用Validator.TryValidateObject时它不起作用。

有什么方法可以做到这一点,而不必编写自定义的TryValidateObject 方法?

【问题讨论】:

    标签: c# .net data-annotations


    【解决方案1】:

    我很惊讶没有人提到MetadataTypeAttribute。但是,是的,这行得通。

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

    至于直接使用接口(使用Customer: ICustomerMetaData):

    产品团队不想实现此功能,主要原因有两个:

    • 与 DataAnnotations.Validator 的一致性

    • 与 ASP.Net MVC 中的验证行为一致

    • 棘手的场景:一个类实现了两个具有相同属性但属性冲突的接口。哪个属性优先?

    虽然 MVC 会自动将 MetaData 注册到 TypeDescriptor,但您可能必须自己手动添加:

      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; }
         }
      }
    

    输出:

    有效 = 假

    有效 = 真

    【讨论】:

    • 不行!!不知道为什么它被赞成,但它肯定不起作用。
    • 不起作用意味着数据注释被忽略。这就是它不起作用的原因。
    • 没有人提到它,因为这只适用于部分类,问题是关于接口的。请在您自己的链接上查看文档。
    【解决方案2】:

    如果您使用基类而不是接口,属性将正常工作。

    【讨论】:

    • 由于类不从其接口继承属性,听起来您将不得不编写自定义验证方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-15
    • 2021-11-12
    • 2016-04-01
    • 2011-01-20
    • 2018-08-11
    相关资源
    最近更新 更多