是否可以将DataAnnotations与接口一起使用?

时间:2011-05-07 06:44:16

标签: c# .net data-annotations

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

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

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

当我尝试使用Validator.TryValidateObject时,它无效。

有没有办法做到这一点而不必编写自定义TryValidateObject方法?

2 个答案:

答案 0 :(得分:40)

我很惊讶没有人提到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自动使用TypeDescriptor注册MetaData,但您可能必须自己手动添加:

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

输出:

  

有效=错误

     

是有效=真

答案 1 :(得分:4)

如果使用基类而不是接口,则属性可以正常工作。