【问题标题】:Skip Executing other Validation Rules in the Fluent validation Ruleset, if one of them fails如果其中一个失败,则跳过执行 Fluent 验证规则集中的其他验证规则
【发布时间】:2017-09-24 11:41:10
【问题描述】:

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

我的 API 端点有以下规则

参数1,参数2,参数3

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.");

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

【问题讨论】:

标签: c# validation servicestack fluent fluentvalidation


【解决方案1】:

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

ValidatorOptions.CascadeMode = CascadeMode.StopOnFirstFailure;

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

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.");
   }
}

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


如果你只想在三个参数都不为空的情况下执行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.");
});

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

 private bool AllParametersSpecified(Request req)
 {
     return !String.IsNullOrEmpty(req.param1) 
         && !String.IsNullOrEmpty(req.param2)
         && !String.IsNullOrEmpty(req.param3);
 }

而且条件将更具可读性:

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

【讨论】:

  • 如果我的函数 IsValidRequest 需要所有 param1、param2、param3 不为空怎么办。谢谢 Sergey 的快速回复。
  • 这很好,但我仍然有一个问题。在调用 IsValidRequest 函数之前,我无法向用户提供 param1 缺失或 param2 缺失的单独消息。现在我只能为无效请求提供错误消息。
  • @anveshtummala 只是不删除参数的验证规则。他们将进行验证。如果指定了所有参数,则 IsValidRequest 验证将运行
  • 容易修复,但对我来说似乎缺少一些灵活性。 CascadeMode = CascadeMode.StopOnFirstFailure;仅适用于每个 Rulefor,但不适用于规则集中的每个 RuleFor
  • @anveshtummala 完全同意你的看法。我还希望在任何规则中的任何验证器失败后可以选择停止验证
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-09-05
  • 1970-01-01
  • 2015-04-19
  • 1970-01-01
  • 1970-01-01
  • 2012-09-21
  • 2019-01-19
相关资源
最近更新 更多