使用 EF 伙伴类上的自定义属性 (AttributeTargets.Class) 进行数据验证

发布于 2024-10-11 05:44:23 字数 1964 浏览 4 评论 0原文

我有一个实体框架生成的类,具有以下属性:

public DateTime LaunchDate;
public DateTime ExpirationDate;

我需要强制执行 ExpirationDate >发布日期。

我正在使用一个伙伴类,如各种帖子中所述。 我正在将自定义验证属性(在属性上)应用于同一好友类中的其他属性,并且这些属性正在工作。

由于我需要比较两个属性,因此我直接在类上使用属性(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 从未被调用。

已经把我的头发拔掉了...

谢谢!

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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

却一份温柔 2024-10-18 05:44:23

通过实现 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;
        }
    }
}

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;
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文