NHirate 验证器开始日期早于结束日期

发布于 2024-11-07 05:55:17 字数 410 浏览 0 评论 0原文

使用 Nhibernate Validator(使用 S#harp Architecture / MVC3),如何编写自定义属性,最好不是特定于对象的属性(因为这是一个相当常见的要求),强制 PropertyA >= PropertyB (或者在更一般的情况下) ,两者都可能为空)。

就像

public DateTime? StartDate { get; set; }

[GreaterThanOrEqual("StartDate")]
public DateTime? EndDate { get; set; }

我看到我可以在特定的 Entity 类中重写 IsValid ,但我不确定这是否是最好的方法,而且我不知道如何提供在这种情况下会出现一条消息。

Using Nhibernate Validator (with S#harp Architecture / MVC3), how can I write a custom attribute, preferably not object-specific (since this is a fairly common requirement) that enforces that PropertyA >= PropertyB (or in the more general case, both may be null).

Something like

public DateTime? StartDate { get; set; }

[GreaterThanOrEqual("StartDate")]
public DateTime? EndDate { get; set; }

I see that I can override IsValid in the particular Entity class but I wasn't sure if that was the best approach, and I didn't see how to provide a message in that case.

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

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

发布评论

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

评论(2

余罪 2024-11-14 05:55:17

当您需要比较对象的多个属性作为验证的一部分时,您需要一个类验证器。然后该属性将应用于类,而不是属性。

我认为没有现有的可以做你想做的事情,但是编写你自己的很容易。

这是一个代码大纲,向您展示验证器的大致样子

[AttributeUsage(AttributeTargets.Class)]
[ValidatorClass(typeof(ReferencedByValidator))]
public class GreaterThanOrEqualAttribute : EmbeddedRuleArgsAttribute, IRuleArgs
{        
    public GreaterThanOrEqualAttribute(string firstProperty, string secondProperty)
    {
        /// Set Properties etc
    }
}

public class ReferencedByValidator : IInitializableValidator<GreaterThanOrEqualAttribute>
{       
    #region IInitializableValidator<ReferencedByAttribute> Members

    public void Initialize(GreaterThanOrEqualAttribute parameters)
    {
        this.firstProperty = parameters.FirstProperty;
        this.secondProperty = parameters.SecondProperty;
    }

    #endregion

    #region IValidator Members

    public bool IsValid(object value, IConstraintValidatorContext constraintContext)
    {
       // value is the object you are trying to validate

        // some reflection code goes here to compare the two specified properties
   }
    #endregion

}

}

When you need to compare multiple properties of an object as part of validation, you need a claass validator. The attribute is then applied to the class, not the property.

I don't think there is an existing one to do what you want, but it is easy enough to write your own.

Here is a code outline to show you roughly what your validator could look like

[AttributeUsage(AttributeTargets.Class)]
[ValidatorClass(typeof(ReferencedByValidator))]
public class GreaterThanOrEqualAttribute : EmbeddedRuleArgsAttribute, IRuleArgs
{        
    public GreaterThanOrEqualAttribute(string firstProperty, string secondProperty)
    {
        /// Set Properties etc
    }
}

public class ReferencedByValidator : IInitializableValidator<GreaterThanOrEqualAttribute>
{       
    #region IInitializableValidator<ReferencedByAttribute> Members

    public void Initialize(GreaterThanOrEqualAttribute parameters)
    {
        this.firstProperty = parameters.FirstProperty;
        this.secondProperty = parameters.SecondProperty;
    }

    #endregion

    #region IValidator Members

    public bool IsValid(object value, IConstraintValidatorContext constraintContext)
    {
       // value is the object you are trying to validate

        // some reflection code goes here to compare the two specified properties
   }
    #endregion

}

}

·深蓝 2024-11-14 05:55:17

目前,如果我需要在模型上执行此操作,我可以让模型实现 IValidatableObject,

public class DateRangeModel : IValidatableObject {

   public DateTime StartDate { get; set; }
   public DateTime EndDate { get; set; }


   public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        List<ValidationResult> results = new List<ValidationResult>();
        if (StartDate > EndDate)
        {
            results.Add(new ValidationResult("The Start Date cannot be before the End Date.", "StartDate"));
        }
        return results;
    }

这似乎提供了与现有系统的良好集成。缺点是,由于这不适用于域对象,因此您需要在那里(或在创建域对象的服务层等中)附加逻辑来从该端强制执行它,以防其他地方使用不同的模型创建或更新域对象。

Currently, if I need to do this on a model, I have the model implement IValidatableObject

public class DateRangeModel : IValidatableObject {

   public DateTime StartDate { get; set; }
   public DateTime EndDate { get; set; }


   public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        List<ValidationResult> results = new List<ValidationResult>();
        if (StartDate > EndDate)
        {
            results.Add(new ValidationResult("The Start Date cannot be before the End Date.", "StartDate"));
        }
        return results;
    }

This seems to provide good integration with the existing system. The drawback is that since this is not applied on the domain object, you need additional logic there (or in a services layer that creates the domain objects, etc.) to enforce it from that end too, in case a different model is used elsewhere to create or update the domain objects.

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