Использование Silvlight, настраиваемый EF POCO, настраиваемая проверка - использование метаданных и их отсутствие в Silverlight 4 - PullRequest
2 голосов
/ 04 декабря 2010

Я использую проверку метаданных для обоих MVC и SIlverlight вместе. Тем не менее, классы для silverlight не работают, и я думаю, что это связано с MetadataTypeAttribute, который не существует для 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? Почему метаданных типа атрибута нет, я не знаю. Есть предложения?

1 Ответ

0 голосов
/ 25 июля 2012

Если вы хотите использовать атрибуты проверки в Silverlight, вы должны сделать одно из трех:

  1. Используйте инструментарий DataGrid для отображения данных - это автоматически проверяет ваши свойства (я видел другие элементы управления, такие как Telerik RadGridView)

  2. Проверьте вручную в установщике свойств и сгенерируйте исключение ValidationException, если значение недопустимо. Вы также должны установить для ValidatesOnExceptions и NotifyOnValidationError значение true в своих привязках.

  3. Реализация INotifyDataErrorInfo или IDataError в вашей модели и установка ошибок проверки с помощью методов в этих интерфейсах.

Вариант 3 является рекомендуемым подходом и выглядит наиболее подходящим для ваших целей.

Проверьте эту ссылку для получения дополнительной информации msdn.microsoft.com/en-us/library/dd901590(v=vs.95).aspx

Наконец, интерфейс INotifyDataErrorInfo может быть немного устрашающим - перед тем, как вы сможете его использовать, нужно разобраться с большим количеством сантехники. Тем не менее, этот пост от Джереми Ликнесса может немного помочь. Обратите внимание, что вам не нужно проверять в установщике, как в примере.

...