2010-09-30 75 views
1

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

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

这里有一个简单的例子:

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提供的验证属性;如果可能的话,我宁愿保持图书馆的生活不受外部核心框架的依赖。

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

回答

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

随着覆盖的地方,验证器工作正常。这是一个更多的工作,但它会完成工作。

我也尝试添加批注作为后备默认规则的基类;这使我有一套基本的规则,并根据具体情况根据需要重写它们。看起来不错。

0

我遇到了同样的问题,无法使用MethadataType为属性注释基类。像滚动锁我做了基本类虚拟属性的重写部分。最重要的是,我为没有虚拟属性做了“遮蔽”。

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