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
为假,并且输入的 Deadline
为 2016-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");
我有这个流畅的验证规则:
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
为假,并且输入的 Deadline
为 2016-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");