Проверка данных с помощью пользовательских атрибутов (AttributeTargets.Class) в классах друзей EF - PullRequest
2 голосов
/ 07 января 2011

У меня есть сгенерированный класс Entity Framework со следующими свойствами:

public DateTime LaunchDate;
public DateTime ExpirationDate;

Мне нужно применить эту ExpirationDate> LaunchDate.

Я использую класс друзей, как описано в различных сообщениях. Я применяю настраиваемые атрибуты проверки (для свойств) к другим свойствам в том же классе приятелей, и они работают.

Поскольку мне нужно сравнить два свойства, я использую атрибут непосредственно в классе (AttributeTargets.Class)

Вот мой пользовательский атрибут проверки:

[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
public class PropertyMustBeGreaterThanAttribute : ValidationAttribute
{
    private const string _defaultErrorMessage = "'{0}' must be greater than '{1}'!";

    public PropertyMustBeGreaterThanAttribute(string property, string greaterThan)
        : base(_defaultErrorMessage)
    {
        GreaterThan = greaterThan;
        Property = property;
    }

    public string Property { get; private set; }
    public string GreaterThan { get; private set; }

    public override string FormatErrorMessage(string name)
    {
        return String.Format(CultureInfo.CurrentUICulture, ErrorMessageString,
            GreaterThan, Property);
    }

    public override bool IsValid(object value)
    {
        PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(value);
        IComparable greaterThan = properties.Find(GreaterThan, true /* ignoreCase */).GetValue(value) as IComparable;
        IComparable property = properties.Find(Property, true /* ignoreCase */).GetValue(value) as IComparable;
        return greaterThan.CompareTo(property) > 0;
    }
}

Сначала я не уверен, к какому классу мне нужно применить атрибут:

[MetadataType(typeof(PromotionValidation))]
[PropertyMustBeGreaterThanAttribute("RetailPrice")] // apply it here
public partial class Promotion
{
    [PropertyMustBeGreaterThanAttribute("ExpirationDate", "LaunchDate")] // or here ???
    public class PromotionValidation
    {

Во-вторых, это не работает, и я понятия не имею, почему !!! Я попытался добавить атрибут для обоих классов. Точки останова в конструкторе достигаются (PropertyMustBeGreaterThanAttribute), но IsValid никогда не вызывается.

Уже выдергиваю волосы ...

Спасибо!

1 Ответ

5 голосов
/ 07 января 2011

Получил работу, реализовав TypeID.Я присвоил атрибут частичному классу:

    [MetadataType(typeof(PromotionValidation))]
    [PropertyMustBeGreaterThanAttribute("RetailPrice", "DiscountedPrice")]
    [PropertyMustBeGreaterThanAttribute("ExpirationDate", "LaunchDate")]
    [PropertyMustBeGreaterThanAttribute("ClaimDeadline", "ExpirationDate")]
    public partial class Promotion
    {
... 

Вот список на случай, если кому-то понадобится:

[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
public class PropertyMustBeGreaterThanAttribute : ValidationAttribute
{
    private const string _defaultErrorMessage = "'{1}' must be greater than '{0}'!";
    private readonly object _typeId = new object();

    public PropertyMustBeGreaterThanAttribute(string property, string greaterThan)
        : base(_defaultErrorMessage)
    {
        GreaterThan = greaterThan;
        Property = property;
    }

    public string Property { get; private set; }
    public string GreaterThan { get; private set; }

    public override string FormatErrorMessage(string name)
    {
        return String.Format(CultureInfo.CurrentUICulture, ErrorMessageString,
            GreaterThan, Property);
    }

    public override bool IsValid(object value)
    {
        PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(value);
        IComparable greaterThan = properties.Find(GreaterThan, true /* ignoreCase */).GetValue(value) as IComparable;
        IComparable property = properties.Find(Property, true /* ignoreCase */).GetValue(value) as IComparable;
        return greaterThan.CompareTo(property) > 0;
    }

    public override object TypeId
    {
        get
        {
            return _typeId;
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...