2010-04-17 84 views
12

我正在使用VS 2010 RTM並嘗試使用MetadataTypeAttribute對簡單類型執行一些基本驗證。當我把驗證屬性放在主類上時,一切正常。但是,當我把它放在元數據類上時,它似乎被忽略了。我一定會錯過一些微不足道的東西,但我現在一直在困擾着這個問題。使用驗證程序時忽略.NET 4 RTM MetadataType屬性

我看過企業庫驗證塊作爲解決方法,但它不支持驗證開箱即用的單個屬性。有任何想法嗎?

class Program 
{ 
    static void Main(string[] args) 
    { 
     Stuff t = new Stuff(); 

     try 
     { 
      Validator.ValidateProperty(t.X, new ValidationContext(t, null, null) { MemberName = "X" }); 
      Console.WriteLine("Failed!"); 
     } 
     catch (ValidationException) 
     { 
      Console.WriteLine("Succeeded!"); 
     } 
    } 
} 

[MetadataType(typeof(StuffMetadata))] 
public class Stuff 
{ 
    //[Required] //works here 
    public string X { get; set; } 
} 

public class StuffMetadata 
{ 
    [Required] //no effect here 
    public string X { get; set; } 
} 

回答

23

這似乎驗證不尊重MetadataTypeAttribute:

http://forums.silverlight.net/forums/p/149264/377212.aspx

的關係必須顯式註冊:

TypeDescriptor.AddProviderTransparent(
     new AssociatedMetadataTypeTypeDescriptionProvider(
      typeof(Stuff), 
      typeof(StuffMetadata)), 
     typeof(Stuff)); 

這個助手類將註冊所有的元數據關係在裝配中:

public static class MetadataTypesRegister 
{ 
    static bool installed = false; 
    static object installedLock = new object(); 

    public static void InstallForThisAssembly() 
    { 
     if (installed) 
     { 
      return; 
     } 

     lock (installedLock) 
     { 
      if (installed) 
      { 
       return; 
      } 

      foreach (Type type in Assembly.GetExecutingAssembly().GetTypes()) 
      { 
       foreach (MetadataTypeAttribute attrib in type.GetCustomAttributes(typeof(MetadataTypeAttribute), true)) 
       { 
        TypeDescriptor.AddProviderTransparent(
         new AssociatedMetadataTypeTypeDescriptionProvider(type, attrib.MetadataClassType), type); 
       } 
      } 

      installed = true; 
     } 
    } 
} 
+1

感謝您的代碼! – aikeru 2012-08-23 17:33:16

+0

爲什麼在MSDN的MetadataTypeAttribute列表中沒有註明這一點?我已經掛了幾個小時b/c在我的MVC項目一切工作正常,但是當創建我的Windows應用程序時,我需要解釋 – 2015-11-03 17:37:20

2

將元數據類的實例而不是主類提供給ValidationContext構造函數似乎適用於我。

+0

這對我'TryValidateProperty',但不幸'TryValidateObject'不幸。 – 2011-07-18 05:44:11

+0

@我只需要ValidateProperty,所​​以我使用這個hack而不是來自接受的答案的全面解決方案,以便使用較短的代碼。 – SlimShaggy 2011-07-18 15:24:14

+0

我得到一個'ArgumentException',提供的實例與提供的validationcontext上的ObjectInstance匹配。 – 2016-01-28 01:01:04