2009-12-09 110 views
3

我正在使用VS2008 SP1,WCF Ria服务2009年7月CTP。我发现MetadataType不偏类模式下工作,真不知道我错过了:元数据类型问题

工作: -

public partial class Person 
{ 
    private string _Name; 

    [Required(AllowEmptyStrings=false, ErrorMessage="Name required entry")] 
    [StringLength(3)] 
    public string Name 
    { 
     set{_Name = value;} 
     get{return _Name;} 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     Person p = new Person { Name="123432" }; 
     List res = new List(); 
     Validator.TryValidateObject(p,new ValidationContext(p,null,null), 
      res,true); 
     if (res.Count > 0) 
     { 
      Console.WriteLine(res[0].ErrorMessage); 
      Console.ReadLine(); 
     } 
    } 
} 

不起作用

public partial class Person 
{ 
    private string _Name; 

    public string Name 
    { 
     set{_Name = value;} 
     get{return _Name;} 
    } 
} 

[MetadataType(typeof(PersonMetadata))] 
public partial class Person 
{ 
} 


public partial class PersonMetadata 
{ 
    [Required(AllowEmptyStrings=false, ErrorMessage="Name required entry")] 
    [StringLength(3)] 
    public string Name; 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     Person p = new Person { Name="123432" }; 
     List res = new List(); 
     Validator.TryValidateObject(p,new ValidationContext(p,null,null), 
      res,true); 
     if (res.Count > 0) 
     { 
      Console.WriteLine(res[0].ErrorMessage); 
      Console.ReadLine(); 
     } 
    } 
} 
+0

我似乎有这个问题,直到我一对System.ComponentModel.DataAnnotations命名空间的引用。 – 2010-07-01 20:57:30

回答

9

编辑:我在这里找到答案:http://forums.silverlight.net/forums/p/149264/377212.aspx

在验证之前,您需要手动注册元数据类:

TypeDescriptor.AddProviderTransparent(
      new AssociatedMetadataTypeTypeDescriptionProvider(typeof(Person), typeof(PersonMetadata)), typeof(Person)); 

     List<ValidationResult> res = new List<ValidationResult>(); 
     bool valid = Validator.TryValidateObject(p, new ValidationContext(p, null, null), res, true); 

(原来的答复如下)

的问题是没有具体与您的局部类,它是Validator.TryValidateObject似乎并没有认识到MetaDataType属性。我有同样的问题 - MVC 2中的内置验证识别元数据类,但TryValidateObject不支持。

看到这些: Validating DataAnnotations with Validator class Validation does not work when I use Validator.TryValidateObject

作为一个方面说明,我不知道这是否是必要的,但我已经看到了元数据类的所有实例使用默认的get /每个属性设置:

[Required(AllowEmptyStrings=false, ErrorMessage="Name required entry")] 
[StringLength(3)] 
public string Name { get; set; } 
+0

也许我错过了一些东西,但.AddProviderTransparent似乎没有被定义。 – 2010-07-27 22:06:54

+0

啊。看起来这是4.0具体。 – 2010-07-27 22:07:28

2

非常感谢杰瑞米Gruenwald上面的答案......我完全被困在这一个。

我想创建一个基于此解决方案的标准验证类,但我不想传入元数据类类型,因为它只是感觉难看。

为了做到这一点,我创建了一个静态类,它对自定义属性进行查找以获取元数据类的类型,然后在返回验证结果之前注册该类。

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.ComponentModel.DataAnnotations; 
using System.Linq; 

namespace MyApp.Validation 
{ 
    public static class EntityValidator 
    { 
     public static List<ValidationResult> Validate(object instance, bool validateAllProperties = true) 
     { 
      RegisterMetadataClass(instance); 

      var validationContext = new ValidationContext(instance, null, null); 
      var validationResults = new List<ValidationResult>(); 

      Validator.TryValidateObject(instance, validationContext, validationResults, validateAllProperties); 

      return validationResults; 
     } 

     private static void RegisterMetadataClass(object instance) 
     { 
      var modelType = instance.GetType(); 
      var metadataType = GetMetadataType(modelType); 

      if (metadataType != null) 
      { 
       TypeDescriptor.AddProviderTransparent(new AssociatedMetadataTypeTypeDescriptionProvider(modelType, metadataType), modelType); 
      } 
     } 

     private static Type GetMetadataType(Type type) 
     { 
      var attribute = (MetadataTypeAttribute)type.GetCustomAttributes(typeof (MetadataTypeAttribute), true).FirstOrDefault(); 
      return attribute == null ? null : attribute.MetadataClassType; 
     } 
    } 
} 

的使用是一个简单的:

var errors = EntityValidator.Validate(myEntity); 
0

如果您正在使用WPF和EF工作,这一直为我工作...

[MetadataType(typeof(Department.Metadata))] 
public partial class Department : BaseModel 
{ 
    static Department() 
    { 
     TypeDescriptor.AddProvider(new AssociatedMetadataTypeTypeDescriptionProvider(typeof(Department),typeof(Metadata)), typeof(Department)); 
    } 
    private sealed class Metadata 
    { 
     [Required(AllowEmptyStrings = false, ErrorMessage = "Department Name is required.")] 
     [StringLength(50, ErrorMessage = "Name must be between 3 and 50 characters.", MinimumLength = 3)] 
     public string Name; 

     [StringLength(250, ErrorMessage = "Name must be between 10 and 250 characters.", MinimumLength = 10)] 
     public string Description; 
    } 
} 

和基类使它发生...

public abstract class BaseModel : IDataErrorInfo 
{ 
    #region Validation 
    string IDataErrorInfo.Error 
    { 
     get { return null; } 
    } 
    string IDataErrorInfo.this[string propertyName] 
    { 
     get 
     { 
      var propertyInfo = GetType().GetProperty(propertyName); 
      var results = new List<ValidationResult>(); 
      var result = Validator.TryValidateProperty(propertyInfo.GetValue(this, null), new ValidationContext(this, null, null) 
      { 
       MemberName = propertyName 
      }, results); 

      if (result) return string.Empty; 
      var validationResult = results.First(); 
      return validationResult.ErrorMessage; 
     } 
    } 
    #endregion 
}