Flagging binding validation rules does not stop on first failure

I have a model:

public class DTO { public int[] StatementItems { get; set; } } 

What I want to check:

  • StatementItems not null
  • StatementItems not empty
  • StatementItems does not contain duplicate identifiers

The verification rule chain I created:

 RuleFor(x => x.StatementItems).NotNull().NotEmpty().Must(x => x.Distinct().Count() == x.Count()); 

And I have a test like:

 _validator.ShouldHaveValidationErrorFor(x => x.StatementItems, null as int[]); 

When I run a test running at zero, I expect it to fire according to the first rule of the chain ( NotNull() ) and stop there. However, he complains that the lamda value used in Must() is null.

Am I mistaken in thinking that Must() should not be run if NotNull() fails? If so, how should this rule be written?

thanks

+5
source share
2 answers

Although @NPras answer provided me with a solution, I did not like the fact that I was duplicating the NotNull rule. After a bit more research on FluentValidation, I implemented it with DependentRules :

 RuleFor(x => x.StatementItems).NotNull().NotEmpty() .DependentRules(d => d.RuleFor(x => x.StatementItems).Must(x => x.Distinct().Count() == x.Count()) ); 

So, now the Must condition is only triggered when the previous two rules apply.

+3
source

I do not see in the FluentValidation documentation that it actually guarantees a short circuit.

If you look in your source:

 public virtual ValidationResult Validate(ValidationContext<T> context) { ... var failures = nestedValidators.SelectMany(x => x.Validate(context)); return new ValidationResult(failures); } 

It will run through * all * validators (using SelectMany() ) and returns a list of errors.

It seems your only option is to force a Must rule check.

 .Must(x => x!= null && x.Distinct().Count() == x.Count()) //or, fluently: .Must(x => x.Distinct().Count() == x.Count()).When(x => x! = null) 

EDIT: I was going to assume that since Validate() is virtual, you can simply override it in your validator to make it short-circuited. But then I realized that the nestedValidators list is private. So yes, no ..

+1
source

Source: https://habr.com/ru/post/1263940/


All Articles