DataAnnotations MetadataType类忽略基类属性

时间:2010-09-30 16:56:54

标签: enterprise-library data-annotations

在尝试使用.NET DataAnnotations功能在派生类中提供简单验证时,我遇到了一些障碍。我使用.NET 4中包含的标准注释(来自System.ComponentModel.DataAnnotations命名空间)标记我的类,然后使用MS Enterprise Library v5验证块来处理规则。

我有一些从公共基类派生的对象,它包含我所有对象共有的属性。出于验证目的,我可能对从此类派生的各种类有不同的规则。

这是一个简化的例子:

public abstract class PersonBase
{
    public int Id { get; set; }
    public string Name { get; set; }
}

[MetadataType(typeof(CustomerMD))]
public class Customer : PersonBase
{

}
[MetadataType(typeof(ManagerMD))]
public class Manager : PersonBase
{

}

public class CustomerMD
{
    [Required]
    [StringLength(20, ErrorMessage="Customer names may not be longer than 20 characters.")]
    public object Name { get; set; }
}

public class ManagerMD
{
    [Required]
    [StringLength(30, ErrorMessage = "Manager names may not be longer than 30 characters.")]
    public object Name { get; set; }
}

// calling code
var invalidCustomer = new Customer {Id=1, Name=string.Empty};
var valFactory = EnterpriseLibraryContainer.Current.GetInstance<ValidatorFactory>();
var customerValidator = valFactory.CreateValidator<Customer>();
var validationResults = customerValidator.Validate(invalidCustomer);
// validationResults.IsValid should equal False, but actually equals True.

我发现如果我将注释推送到基类,我可以得到预期的验证结果,但是我失去了满足不同类型的不同要求的能力。此外,如果我将特定于类的属性放在派生类上并为这些属性提供元数据,我会得到结果,但仅适用于这些属性,而不是基类的属性。

我还没有尝试过使用EntLib提供的验证属性;如果可能的话,我宁愿保持库中的库不受核心框架之外的依赖。

我错过了什么,或者我在这里运气不好?

2 个答案:

答案 0 :(得分:1)

我认为我有一个可行的解决方案。

似乎Metadata类不会提供属于目标对象超类的属性的验证。为了让元数据与此一起使用,我需要将超类属性标记为虚拟,然后为我想要验证的属性提供覆盖。

示例(参见上面原始示例的问题):

public abstract class PersonBase
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
}
[MetadataType(typeof(CustomerMD))]
partial class Customer : PersonBase
{
    public override string Name
    {
        get
        {
            return base.Name;
        }
        set
        {
            base.Name = value;
        }
    }
}

在覆盖到位后,验证器按预期工作。这是一项更多的工作,但它将完成工作。

我还尝试将注释添加到基类作为回退默认规则;这允许我有一组基本规则,并根据需要逐个覆盖它们。看起来不错。

答案 1 :(得分:0)

我遇到了同样的问题,并且无法使用MethadataType使用Attributes注释基类。与Scroll Lock一样,我为基类虚拟属性做了重写部分。最重要的是,我制作了#34;影子&#34;对于无虚拟属性。

&#13;
&#13;
public class BaseClass
{
  public virtual int Id {get;set;}

  public string Name {get;set;}
}


public class DerivedClass
{
   [SomeAttribute]
   public ovveride int Id {get{ return base.Id;} set{ base.Id = value;}}

   [SomeAttribute]
   public new string Name {get{ return base.Name;} set{ base.Name = value;}}
}
&#13;
&#13;
&#13;