使用Silvlight,自定义EF POCO,自定义验证 - 利用元数据,而不是在Silverlight 4中工作

时间:2010-12-04 00:48:02

标签: silverlight reflection metadatatype

我正在为我的MVC和SIlverlight使用元数据验证。然而,silverlight的类不起作用,我认为它是由于Silverlight 4不存在的MetadataTypeAttribute。这似乎是我的项目的这一部分唯一的东西...我试图避免做的事情自定义,因为我不想重新发明轮子,但验证类似乎没有呈现预期的结果..:

以下是我的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的元数据类?为什么metadatatype属性不存在我不知道。有什么建议吗?

1 个答案:

答案 0 :(得分:0)

如果要在Silverlight中使用验证属性,则必须执行以下三项操作之一:

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

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

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

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

    查看此链接了解更多信息msdn.microsoft.com/en-us/library/dd901590(v = vs.95).aspx

    最后,INotifyDataErrorInfo界面可能有点令人生畏 - 在你可以使用它之前有很多管道可以解决。但是,Jeremy Likness的this post可能会有所帮助。 请注意,您不必像示例中那样在setter中进行验证。