2010-09-30 97 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;}} 
 
}