FluentValidation规则链接不会在第一次失败时停止

ADr*_*ger 6 c# fluentvalidation

我有一个模特:

public class DTO
{
    public int[] StatementItems { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我要验证的是:

  1. StatementItems 不是空的
  2. StatementItems 不是空的
  3. StatementItems 不包含任何重复的ID

我创建的验证规则链是:

RuleFor(x => x.StatementItems).NotNull().NotEmpty().Must(x => x.Distinct().Count() == x.Count());
Run Code Online (Sandbox Code Playgroud)

我有一个测试:

_validator.ShouldHaveValidationErrorFor(x => x.StatementItems, null as int[]);
Run Code Online (Sandbox Code Playgroud)

当我运行测试传递一个空值时,我希望它在chain(NotNull())的第一个规则上失败并停在那里.但是,它抱怨使用的lamda值为Must()null.

我认为Must()如果NotNull()失败不应该运行我错了吗?如果是这样,该规则应如何编写?

谢谢

ADr*_*ger 9

尽管@ NPras的回答确实为我提供了一个解决方案,但我不喜欢我复制NotNull规则的事实.在对FluentValidation进行了一些研究后,我使用DependentRules以下方法实现了它:

RuleFor(x => x.StatementItems).NotNull().NotEmpty()
            .DependentRules(d =>
                d.RuleFor(x => x.StatementItems).Must(x => x.Distinct().Count() == x.Count())
            );
Run Code Online (Sandbox Code Playgroud)

所以现在Must只有在前两个规则有效时才会触发条件.


Sys*_*Lol 5

查看 FluentValidation 的级联模式。您可以在第一次失败时使其短路,如下所示:

this.RuleFor(x => x.StatementItems)
   .Cascade(CascadeMode.Stop)
   .NotNull()
   .NotEmpty()
   .Must(x => x.Distinct().Count() == x.Count());
Run Code Online (Sandbox Code Playgroud)

此外,您可以在AbstractValidator子类的构造函数中配置它。那么你就不需要把它放在每条规则上。

public MyInputValidator()
{
  this.CascadeMode = CascadeMode.Stop;
}
Run Code Online (Sandbox Code Playgroud)