我有这个流畅的验证规则:
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条件相关联。
我遇到的问题是,第二个条件影响第一个必须规则。例如,如果tvm.Task.Instructed
为false,输入的Deadline
为2016-06-22
(并考虑到当前日期为2016-06-23),我希望收到{{1} } 信息。但我没有收到该消息,因为第二次检查Deadline can't be earlier than today
是否为真并返回false。所以似乎当条件不仅影响它遵循的规则。我真的想在一行中流利地编写这些规则。这是可能的,或者除了单独定义之外别无选择。
答案 0 :(得分:1)
嗯,默认情况下,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");