2010-04-17 89 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