[英]FluentValidation rules chaining not stopping at first failure
我有一個模型:
public class DTO
{
public int[] StatementItems { get; set; }
}
我想驗證一下:
StatementItems
不為空StatementItems
不為空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.