Search code examples
c#fluentvalidation

Order of DependentRules in FluentValidation


I have the model like

public class Command : IRequest<bool>
{
    public int Id { get; set; }
    public int LabelId { get; set; }
    public int UserId { get; set; }
}

And fluent validator

public class Validator : AbstractValidator<Command>
{
    public Validator(DbContext dbContext)
    {
        RuleFor(q => q.LabelId).GreaterThan(0);
        RuleFor(q => q.UserId).GreaterThan(0);
        RuleFor(q => q.Id).GreaterThan(0);
        RuleFor(t => t.Id).GreaterThan(0).DependentRules(() =>
            RuleFor(q => q.Id).SetValidator(new EntityExistsValidator(dbContext)));
    }
}

where EntityExistsValidator is custom PropertyValidator that makes call to database to check if entity exists.

How can I call this validator only when all rules applied and model is valid?

Example

Property  |  Value |  `EntityExistsValidator` run
-------------------------------------------------
LabelId   |    0   |  no
UserId    |    0   |  no
Id        |    0   |  no

so, it should not run when validation is fail. Only when model is valid. How can I achieve that?


Solution

  • My suggestion would be to use a PreValidator class`:

    public class Validator : AbstractValidator<Command>
    {
        private class PreValidator : AbstractValidator<Command>
        {
            internal PreValidator()
            {
                RuleFor(q => q.LabelId).GreaterThan(0);
                RuleFor(q => q.UserId).GreaterThan(0);
                RuleFor(q => q.Id).GreaterThan(0);
            }
        }
    
        public Validator(DbContext dbContext)
        {
            RuleFor(x => x)
              .SetValidator(new PreValidator())
              .DependentRules(() => RuleFor(q => q.Id)
                  .SetValidator(new EntityExistsValidator(dbContext)));
        }
    }