如果其中一个失败,则跳过Fluent验证规则集中的执行其他验证规则

anv*_*ala 2 c# validation fluent fluentvalidation servicestack

如果其中一个失败,是否有任何方法可以跳过在Ruleset中执行验证规则.

我的API端点有以下规则

param1,param2,param3

RuleSet  => 
     RuleFor(req => req.param1).NotEmpty().WithMessage("param1 is missing.");
     RuleFor(req => req.param2).NotEmpty().WithMessage("param2 is missing.");
     RuleFor(req => req.param3).NotEmpty().WithMessage("param3 is missing.");
     RuleFor(req => req.param1).Must((req, param1) => IsValidRequest(req)).WithMessage("Invalid request.");
Run Code Online (Sandbox Code Playgroud)

在我的IsValidRequest(req)中,我再次必须在进行自定义验证之前验证param1,param2,param3,即使上述规则失败,所有其他验证仍将继续尝试.

Ser*_*kiy 8

默认情况下,FluentValidation使用Continue级联模式在规则定义中调用验证器(即它调用所有验证器).StopOnFirstFailure在第一个验证器失败后,您应该使用mode来停止执行:

ValidatorOptions.CascadeMode = CascadeMode.StopOnFirstFailure;
Run Code Online (Sandbox Code Playgroud)

请注意,这将StopOnFirstFailure全局设置模式.如果要为特定验证器指定此模式,可以使用validator类的属性:

public class RequestValidator : AbstractValidator<Request>
{
   public RequestValidator()
   {
       CascadeMode = CascadeMode.StopOnFirstFailure;

       RuleFor(req => req.param1)
          .NotEmpty().WithMessage("param1 is missing.")
          .Must((req, param1) => IsValidRequest(req)).WithMessage("Invalid request.");
       RuleFor(req => req.param2).NotEmpty().WithMessage("param2 is missing.");
       RuleFor(req => req.param3).NotEmpty().WithMessage("param3 is missing.");
   }
}
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,Must如果NotEmpty验证器失败,则不会执行验证器.


如果只想Must在所有三个参数都不为空时执行验证器,那么这When是最佳选择:

When(req => !String.IsNullOrEmpty(req.param1) 
         && !String.IsNullOrEmpty(req.param2)
         && !String.IsNullOrEmpty(req.param3), () => {
     RuleFor(req => req.param1)
        .Must((req, param1) => IsValidRequest(req)).WithMessage("Invalid request.");
});
Run Code Online (Sandbox Code Playgroud)

您可以将前置条件检查移动到单独的方法:

 private bool AllParametersSpecified(Request req)
 {
     return !String.IsNullOrEmpty(req.param1) 
         && !String.IsNullOrEmpty(req.param2)
         && !String.IsNullOrEmpty(req.param3);
 }
Run Code Online (Sandbox Code Playgroud)

并且条件更具可读性:

When(AllParametersSpecified, () => {
     RuleFor(req => req.param1)
        .Must((req, param1) => IsValidRequest(req)).WithMessage("Invalid request.");
});
Run Code Online (Sandbox Code Playgroud)

  • 很容易修复,但对我来说似乎缺少一些灵活性。CascadeMode = CascadeMode.StopOnFirstFailure; 仅适用于每个 Rulefor 内部,但不适用于规则集中的每个 RuleFor (2认同)
  • @anveshtummala完全同意你的看法.我希望在任何规则中的任何验证器失败后都可以选择停止验证 (2认同)