簡體   English   中英

FluentValidation 規則鏈在第一次失敗時不會停止

[英]FluentValidation rules chaining not stopping at first failure

我有一個模型:

public class DTO
{
    public int[] StatementItems { get; set; }
}

我想驗證一下:

  1. StatementItems不為空
  2. StatementItems不為空
  3. StatementItems不包含任何重復的 ID

我創建的驗證規則鏈是:

RuleFor(x => x.StatementItems).NotNull().NotEmpty().Must(x => x.Distinct().Count() == x.Count());

我有一個測試:

_validator.ShouldHaveValidationErrorFor(x => x.StatementItems, null as int[]);

當我運行傳入空值的測試時,我希望它在鏈的第一條規則( NotNull() )上失敗並停止。 但是,它抱怨Must()使用的 lamda 值為空。

如果NotNull()失敗,我認為Must()不應該運行是NotNull()嗎? 如果是這樣,這個規則應該怎么寫?

謝謝

盡管@NPras 的回答確實為我提供了解決方案,但我不喜歡我正在復制 NotNull 規則這一事實。 在對 FluentValidation 進行了更多研究之后,我使用DependentRules實現了它:

RuleFor(x => x.StatementItems).NotNull().NotEmpty()
            .DependentRules(d =>
                d.RuleFor(x => x.StatementItems).Must(x => x.Distinct().Count() == x.Count())
            );

所以現在只有在前兩個規則有效時才會觸發Must條件。

查看 FluentValidation 的級聯模式 您可以在第一次失敗時使其短路,如下所示:

this.RuleFor(x => x.StatementItems)
   .Cascade(CascadeMode.Stop)
   .NotNull()
   .NotEmpty()
   .Must(x => x.Distinct().Count() == x.Count());

此外,您可以在AbstractValidator子類的構造函數中配置它。 那么你就不需要把它放在每條規則上。

public MyInputValidator()
{
  this.CascadeMode = CascadeMode.Stop;
}

我在FluentValidation文檔中沒有看到它實際上保證短路。

如果你查看它的來源:

public virtual ValidationResult Validate(ValidationContext<T> context)
{
  ...
  var failures = nestedValidators.SelectMany(x => x.Validate(context));
  return new ValidationResult(failures);
}

它將運行*所有*驗證器(使用SelectMany() )並返回錯誤列表。

您唯一的選擇似乎是強制檢查您的Must規則。

.Must(x => x!= null && x.Distinct().Count() == x.Count())
//or, fluently:
.Must(x => x.Distinct().Count() == x.Count()).When(x => x! = null)

編輯:我打算建議,由於Validate()是虛擬的,您可以在驗證器中覆蓋它以使其短路。 但后來我意識到nestedValidators列表是私有的。 所以是的,不..

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM