FluentValidation Must 规则受遵循另一个 Must 规则的 When 条件影响

FluentValidation Must rule affected by When condition that follows another Must rule

我有这个流畅的验证规则:

    RuleForEach(tvm => tvm.Task.Executors).Cascade(CascadeMode.StopOnFirstFailure).Must((tvm, exec) => { return exec.Deadline.HasValue ? exec.Deadline.Value.Date >= DateTime.Now.Date : true; }).
        When(tvm=>!tvm.Task.Instructed).
        WithMessage("Deadline can't be earlier than today").
        Must((tvm,exec)=>{ return exec.Deadline.HasValue ? exec.Deadline.Value.Date >= tvm.Task.InstructDate.Value.Date : true; }).
        When(tvm=>tvm.Task.Instructed).
        WithMessage("Deadline can't be earlier than the instructed date").
        Must((tvm, exec) => { return exec.InstructionId == (int)Instructions.TakeOwnership ? exec.Deadline != null : true; }).
        WithMessage("Enter deadline");

如您所见,有 3 个必须规则。前 2 个与 When 条件相关。 我遇到的问题是,第二个 When 条件会影响第一个 Must 规则。例如,如果 tvm.Task.Instructed 为假,并且输入的 Deadline2016-06-22(并考虑到当前日期为 2016-06-23),我希望收到 Deadline can't be earlier than today 信息。但我没有收到该消息,因为第二个 When 检查 tvm.Task.Instructed 是否为真且 returns 为假。所以看起来 When 条件不仅影响它遵循的规则。我真的很想在一行中流利地写出这些规则。这可能吗?或者我别无选择,只能单独定义它们。

嗯,默认情况下,When 条件适用于所有验证器。

查看When扩展方法的源代码,你有一个具有此默认值的参数。

public static IRuleBuilderOptions<T, TProperty> Unless<T, TProperty>(this IRuleBuilderOptions<T, TProperty> rule, Func<T, bool> predicate, ApplyConditionTo applyConditionTo = ApplyConditionTo.AllValidators) {
            predicate.Guard("A predicate must be specified when calling Unless");
            return rule.When(x => !predicate(x), applyConditionTo);
        }

因此更改您的 When,添加 ApplyConditionTo.CurrentValidator

所以这应该没问题(用一些样本数据测试)

RuleForEach(tvm => tvm.Task.Executors).
        Cascade(CascadeMode.StopOnFirstFailure).
        Must((tvm, exec) => { return exec.Deadline.HasValue ? exec.Deadline.Value.Date >= DateTime.Now.Date : true; }).
        When(tvm=>!tvm.Task.Instructed, ApplyConditionTo.CurrentValidator).
        WithMessage("Deadline can't be earlier than today").
        Must((tvm,exec)=>{ return exec.Deadline.HasValue ? exec.Deadline.Value.Date >= tvm.Task.InstructDate.Value.Date : true; }).
        When(tvm=>tvm.Task.Instructed, ApplyConditionTo.CurrentValidator).
        WithMessage("Deadline can't be earlier than the instructed date").
        Must((tvm, exec) => { return exec.InstructionId == (int)Instructions.TakeOwnership ? exec.Deadline != null : true; }).
        WithMessage("Enter deadline");