简体   繁体   English

使用FluentValidation验证互斥字段

[英]Using FluentValidation to validate mutually exclusive fields

I'm attempting to validate that only one of three fields has a value using FluentValidation. 我试图使用FluentValidation验证三个字段中只有一个具有值。

RuleFor(x => x.Date1)
            .Must(x => !x.HasValue)
            .When(x => x.Date2.HasValue || x.Date3.HasValue)
            .WithMessage("Select only one of Date 1, Date 2 and Date 3");

This is repeated for the other 2 dates. 其他2个日期重复此操作。 As would be expected, this produces on message per rule that matches. 正如所料,这会产生匹配的每条规则的消息。

There are other rules involved, so is there a way to execute the other rules but fail on the first of these three? 还有其他规则,所以有没有办法执行其他规则,但在这三个中的第一个失败? I've seen where I could set CascadeMode.StopOnFirstFailure globally but I want the other rules outside of these three to work as they currently do. 我已经看到我可以在全球范围内设置CascadeMode.StopOnFirstFailure ,但我希望这三个规则之外的其他规则能够像现在一样工作。

I decide to go down another route. 我决定沿着另一条路走下去。 It feels elegant but I'll know if it passes the code review. 它感觉很优雅,但我知道它是否通过了代码审查。

I created a new property 我创建了一个新属性

    public IEnumerable<DateTime?> MutuallyExclusiveDates
    {
        get
        {
            return new List<DateTime?>()
            {
                Date1,
                Date2,
                Date3
            };

        }
    }

Then I added this rule 然后我添加了这个规则

 RuleFor(x => x.MutuallyExclusiveDates)
            .Must(x => x.Count(d => d.HasValue) <= 1)
            .WithMessage("Select only one of Date 1, Date 2 and Date 3");

I would use something like 我会用类似的东西

RuleFor(x => x).Must(ValidateDates).WithName("something");

<snip/>

private bool ValidateDates(SomeRequest request)
{
   //perform logic and return true/false;
}

Inside the ValidateDates method you have access to the full request. ValidateDates方法中,您可以访问完整请求。

For more examples of complex validation using Must take a look at this post - http://nodogmablog.bryanhogan.net/2015/04/complex-model-validation-using-fluent-validation/ 对于复杂的验证的更多示例使用Must看看这篇文章- http://nodogmablog.bryanhogan.net/2015/04/complex-model-validation-using-fluent-validation/

Simple one rule for all 3 using xor. 使用xor的所有3个简单的一条规则。 No extra properties needed. 无需额外的属性。 take out the unless if you want to force at least one to have a value. 除非你想强迫至少一个人拥有一个价值,否则取出。

 RuleFor(x => x).Cascade(CascadeMode.StopOnFirstFailure)
     .Must(x => (x.date1.HasValue ^ x.date2.HasValue) ^ x.date3.HasValue)
     .Unless(x => !x.date1.HasValue && !x.date2.HasValue && !x.date3.HasValue)
     .WithMessage("Select only one of Date 1, Date 2 and Date 3");

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM