FluentValidation:在子集合规则中使用父属性值

Eri*_*rik 3 c# fluentvalidation

我有这个验证器:

 public class InputValidator : AbstractValidator<InputData>
{
    public InputValidator()
    { 
        RuleFor(inputData => inputData.Ucl).GreaterThan(0).....;

        RuleForEach(inputData => inputData.Loads).ChildRules(inputData => {            
              inputData.RuleFor(load => load.Position).GreaterThan(0).....); 
            });
... etc
Run Code Online (Sandbox Code Playgroud)

但是:位置(在每个负载中)也必须小于 Ucl(在输入数据中)。如何为这种关系(父参数与子参数)制定规则?

rgv*_*lee 8

我认为没有一种很好的内联方法。子规则不允许您传入父对象。Must我认为Custom(通过context.ParentContext.InstanceToValidate也许)将允许您添加涉及父级和子级的规则,但规则将针对集合而不是每个项目。更好的方法,以及我通常的做法是为您的Load实体创建一个子验证器:

public class LoadValidator : AbstractValidator<Load>
{
    public LoadValidator(InputData inputData)
    {
        RuleFor(load => load.Position)
                .GreaterThan(0).WithMessage("Position must be greater than 0")
                .LessThan(inputData.Ucl).WithMessage("Position must be less than Ucl");     
    }
}
Run Code Online (Sandbox Code Playgroud)

这变得可重用并且更容易测试。然后SetValidator使用它。

public class InputDataValidator : AbstractValidator<InputData>
{
    public InputDataValidator()
    {
        RuleFor(inputData => inputData.Ucl)
            .GreaterThan(0).WithMessage("Ucl must be greater than 0");

        RuleForEach(inputData => inputData.Loads)
            .SetValidator(inputData => new LoadValidator(inputData));
    }
}
Run Code Online (Sandbox Code Playgroud)

可重用的属性验证器可能是另一种方法,但对我来说,它必须是一个相当高水平/通用的情况才能实现它。