I have this validator:
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
However: Position (in each load) must also be less than Ucl (in InputData). How can I make a rule for such a relation (parent parameter vs. child parameter)?
I don't think there is a nice way to do it inline. Child rules doesn't allow you to pass in the parent object. Must
and I think Custom
(via context.ParentContext.InstanceToValidate
maybe) would allow you to add rules(s) involving both the parent and child but the rule(s) would be against the collection rather than each item. The better way, and how I'd normally do it would be to create a child validator for your Load
entity:
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");
}
}
This becomes reusable and a lot easier to test. Then use SetValidator
to use it.
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));
}
}
Reusable property validators could be another way of doing it, but for me it'd have to be a reasonably high level/generic case to bother with implementing one.