Data validation with custom attributes (AttributeTargets.Class) on EF buddy classes

天大地大妈咪最大 提交于 2019-11-30 20:00:02

问题


I have an Entity Framework generated class with the following properties:

public DateTime LaunchDate;
public DateTime ExpirationDate;

I need to enforce that ExpirationDate > LaunchDate.

I am using a buddy class as described in various posts. I am applying custom validation attributes (on properties) to other properties in the same buddy class and these are working.

Since I need to compare two properties I am using an attribute directly on the class (AttributeTargets.Class)

Here is my custom validation attribute:

[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;
    }
}

First I am unsure to which class I need to apply the attribute to:

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

Second, it's not working and I have no clue why!!! I've tried adding attribute to both classes. Breakpoints in the constructor are hit (PropertyMustBeGreaterThanAttribute ), but IsValid is never called.

Pulling my hair out already....

Thanks!


回答1:


Got it to work by implementing TypeID. I assigned the attribute to the partial class:

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

Here is the listing in case anyone needs it:

[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;
        }
    }
}


来源:https://stackoverflow.com/questions/4621210/data-validation-with-custom-attributes-attributetargets-class-on-ef-buddy-clas

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!