Что дает запрос атрибута, не приводящий к базовому типу атрибута? - PullRequest
2 голосов
/ 06 января 2010

Я пытаюсь запросить атрибуты и получить доступ к базовому типу нескольких атрибутов. По какой-то причине он не работает правильно и не выполняется так, как ожидалось. Вот код ниже:

    internal static void ValidateProperties(TModel model, ModelStateDictionary modelState)
    {
        Type type = model.GetType();            
        PropertyInfo[] properties = type.GetProperties();
        foreach (PropertyInfo property in properties)
        {                
            foreach(Attribute attribute in property.GetCustomAttributes(true))
            {
                ValidationAttribute validationAttribute = attribute as ValidationAttribute;
                if (validationAttribute != null)
                {                        
                    if (!validationAttribute.IsValid(property.GetValue(model, null)))
                        modelState.AddModelError(property.Name, validationAttribute.ErrorMessage);
                }
            }
        }            
    } 

По какой-то причине validateAttribute всегда имеет значение null. При отладке он не будет приводить CustomValidationAttribute или RequiredAttribute. Попытка прямого преобразования в ValidationAttribute вместо использования ключевого слова «as» также приводит к исключению Invalid Cast для обоих этих типов. Очевидно, что они получены из атрибута Validation: http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.validationattribute.aspx

Чего мне не хватает? Спасибо!


Редактировать: для каждого запроса я добавил оператор Debug для вывода типа атрибута. Результаты следующие:

System.ComponentModel.DataAnnotations.CustomValidationAttribute System.ComponentModel.DataAnnotations.RequiredAttribute System.ComponentModel.DataAnnotations.RegularExpressionAttribute System.ComponentModel.DataAnnotations.CustomValidationAttribute System.ComponentModel.DataAnnotations.RequiredAttribute

Ответы [ 2 ]

2 голосов
/ 06 января 2010

Не похоже, что вы что-то упускаете или делаете что-то не так, так что вот вам выстрел в темноте: сборки (запрашивающие и запрашиваемые) используют разные (со строгими именами) версииSystem.ComponentModel.DataAnnotations.dll

0 голосов
/ 06 января 2010

EDIT:

Перед фактическим кастом, пожалуйста, проверьте тип для Атрибута.

Вместо прямого литья ..

ValidationAttribute validationAttribute = attribute as ValidationAttribute;

Проверьте ..

if(!(attribute is ValidationAttribute))
{
    continue;
}
ValidationAttribute validationAttribute = attribute as ValidationAttribute;

Оригинал:

Вот как вы можете это сделать.

Зачем перебирать все атрибуты свойства, а не фильтровать все свойства, имеющие атрибут типа ValidationAttribute.

        PropertyInfo[] properties = model.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);

        var valProps = from PropertyInfo property in properties
                       where property.GetCustomAttributes(typeof(ValidationAttribute), true).Length > 0
                       select new
                       {
                           Property = property,
                           ValidationAttributes = property.GetCustomAttributes(typeof(ValidationAttribute), true)
                       };

        foreach (var item in valProps)
        {
            foreach (ValidationAttribute attribute in item.ValidationAttributes)
            {
                if (attribute.IsValid(item.Property.GetValue(model, null)))
                {
                    continue;
                }

                //Validation fails..
            }
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...