2010-12-04 58 views
2

我正在为我的MVC和SIlverlight一起使用元数据验证。然而,silverlight的类没有工作,我认为它归因于Silverlight 4中不存在的MetadataTypeAttribute。这似乎是我的项目的这部分所持有的唯一东西......我试图避免做到这一点风俗我不喜欢推倒重来,但是验证类似乎没有呈现预期的结果..:使用Silvlight,自定义EF POCO,自定义验证 - 利用元数据及其在Silverlight 4中不工作

这里是我的CLR解决方案:

var metadataAttrib = this.GetType().GetCustomAttributes(typeof(MetadataTypeAttribute), true).OfType<MetadataTypeAttribute>().FirstOrDefault(); 
      var buddyClassOrModelClass = metadataAttrib != null ? metadataAttrib.MetadataClassType : this.GetType(); 
      var buddyClassProperties = TypeDescriptor.GetProperties(buddyClassOrModelClass).Cast<PropertyDescriptor>(); 
      var modelClassProperties = TypeDescriptor.GetProperties(this.GetType()).Cast<PropertyDescriptor>(); 

     var brokenRules = from buddyProp in buddyClassProperties 
          join modelProp in modelClassProperties on buddyProp.Name equals modelProp.Name 
          from attribute in buddyProp.Attributes.OfType<ValidationAttribute>() 
          where !attribute.IsValid(modelProp.GetValue(this)) 
          select new BrokenRule() { FieldName = buddyProp.Name, ErrorMessage = attribute.FormatErrorMessage("") }; 

     brokenRulesList = brokenRules.ToList(); 

...这里是代码为Silverlight

var metadataAttrib = this.GetType().GetCustomAttributes(typeof(MetadataTypeAttribute), true).OfType<MetadataTypeAttribute>().FirstOrDefault(); 
      var buddyClassOrModelClass = metadataAttrib != null ? metadataAttrib.MetadataClassType : this.GetType(); 
      var buddyClassProperties = buddyClassOrModelClass.GetType().GetProperties(); 
      var modelClassProperties = this.GetType().GetProperties(); 

      var validationContext = new ValidationContext(this, null, null); 

      var validationResults = from buddyProp in buddyClassProperties 
           join modelProp in modelClassProperties on buddyProp.Name equals modelProp.Name 
           from attribute in buddyProp.GetCustomAttributes(true).OfType<ValidationAttribute>().Cast<ValidationAttribute>() 
           where buddyProp.Name == modelProp.Name 
           select attribute.GetValidationResult(modelProp, validationContext); 

      brokenRulesList = new List<BrokenRule>(); 
      foreach (ValidationResult vr in validationResults) 
      { 
       foreach (string memberName in vr.MemberNames) 
        brokenRulesList.Add(new BrokenRule() { FieldName = memberName, ErrorMessage = vr.ErrorMessage }); 

      } 

...但是,Silverlight的代码不工作..这里是测试案例...

[MetadataType(typeof(UserMetadata))] 
    public partial class User 
    { 
     public partial class UserMetadata 
     { 

     [Required(ErrorMessageResourceName = "UserIDValidationMessage", ErrorMessageResourceType = typeof(AppResources))] 
      public System.Guid ID { get; set; } 

      public Nullable<int> UID { get; set; } 

     [Display(Name="UserUsernameLabel", Description="Username", ResourceType=typeof(AppResources))] 
     [Required(ErrorMessageResourceName = "UserUsernameValidationMessage", ErrorMessageResourceType = typeof(AppResources))] 
     [StringLength(70, ErrorMessageResourceName="UserUsernameValidationMessage", ErrorMessageResourceType = typeof(AppResources))] 
      public string Username { get; set; } 

     [Display(Name="UserFirstNameLabel", Description="First Name", ResourceType=typeof(AppResources))] 
     [StringLength(90, ErrorMessageResourceName="UserFirstNameValidationMessage", ErrorMessageResourceType = typeof(AppResources))] 
      public string FirstName { get; set; } 
} 

我做了一个类为Silverlight,它可以让编译它,但它不工作 - 如预期..

using System; 
using System.Reflection; 

namespace System.ComponentModel.DataAnnotations 
{ 
    public class MetadataTypeAttribute : Attribute 
    { 
     public MetadataTypeAttribute(Type t) 
     { 
      MetadataClassType = t; 
     } 

     public Type MetadataClassType 
     { 
      get; 
      set; 
     } 

    } 
} 

有谁知道如何简单地利用元数据类为silverlight?为什么metadatatypeattribute不在那里我不知道。有什么建议么?

回答

0

如果你想使用验证在Silverlight属性,你必须做的三两件事之一:

  1. 使用的工具包DataGrid中显示的数据 - 这会自动验证您的属性(我所看到的其他控件请执行此操作,例如Telerik的RadGridView)

  2. 在属性设置器中手动验证并在值无效时抛出ValidationException。您还必须在Bindings中将ValidatesOnExceptions和NotifyOnValidationError设置为true。

  3. Implement INotifyDataErrorInfo or IDataError在您的模型中,并通过这些接口中的方法设置验证错误。

选项3是推荐的方法,看起来最适合您的目的。

看看这个链接获取更多信息msdn.microsoft.com/en-us/library/dd901590(v=vs.95).aspx

最后,INotifyDataErrorInfo接口可以是一个有点令人生畏 - 有在你使用它之前,需要找出许多管道。但是,来自Jeremy Likness的this post可能会有所帮助。 请注意,您不必像在示例中那样在setter中进行验证。