2009-12-09 90 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 
}