Here in this article we are going to discuss about cascade modes supported by fluent validation. There are two modes – rule level cascade mode and class level cascade mode. The article is relevant to Fluent Validation 11. It explains how these cascade modes can be set and how do they affect the behavior of the validators.
Let’s get started !
We have seen how to declare validation rules in previous posts about fluent validation. This article is going to be an extension to the previous articles. Below is the list of articles in case you want to refer them:
- Adding Fluent Validation in ASP .NET Core Web APIs
- ASP .NET Core API – Placeholders in Fluent Validation Messages
- ASP .NET Core API – Fluent Validations – Customizing Messages
- ASP .NET Core API – Fluent Validations – Collections
- ASP .NET Core API – Fluent Validators and Dependency Injection
Example – CourseValidator
Let’s first understand what does the cascading mean for fluent validation. In the validator, one or more rules can be added inside the constructor by using
RuleFor method. Let’s consider a simple validator shown in the code snippet given below.
Here there are two rules in the validator class. First rule for ID has single validator, to validate that the ID should be greater than zero. The second rule has multiple validations chained. The first validator checks that the string should not be null. Then subsequent validators are for checking minimum and maximum allowed lengths of the input.
What does happen if a validation is failed ? Should next rules and validations be evaluated ? This is decided by the cascade level. There are two cascade levels supported – class level cascade mode and rule level cascade mode.
What does class level cascade mode mean ?
Let’s say ID is zero. Then the validation specified in the first rule will fail. What should happen now ? Should the validations specified for name be evaluated even though there is one failure already in the validator ?
The class level cascade mode decides if next rule should be evaluated if a rule has failed. It has nothing to do with validators.
There are two supported cascade modes :
- Continue (the default value), which means even if a rule has validation failure, all the next rules should be evaluated
- Stop, which means the validator should stop when a validation inside a rule fails. Next rules should not be evaluated by the validator.
So, class level cascade mode decides whether the execution should stop at the rule level.
What does rule level cascade mode mean ?
Let’s now talk about the second rule in the Course validator. It first checks if name is not null. Then there are validators specified for checking length of the input.
Let’s say the input Name is null. what would happen then ? The
NotNull validator would fail. But would this failure stop the execution of next validation ?
This behavior is decided by rule level cascade mode. There are two supported values for this mode too:
- Continue, this is the default, and it means all the validators specified in a rule should be executed, regardless of the failures
- Stop, which means the execution of validators should be stopped after first validation fails.
With the default cascade mode, continue, if the Name is null, the validator will continue to next validation, the lengths validation. If we want to change this behavior, then we can set the rule level cascade mode should be set to Stop. In this case, the next rules would still be evaluated.
So, we know now what are different cascade modes. It’s time now to understand how these modes should be set. For every rule, there is a Cascade method which can be used to rule level cascade mode as shown in the code snippet given below.
Using above method, we need to set the rule level cascade mode for every rule that we define in the validator. If we want to apply same rule level cascade mode to all the rules in the validator, then we can set the property
RuleLevelCascadeMode to appropriate cascade mode. Similarly, there is a property
ClassLevelCascadeMode which can be set as shown in the code snippet given below.
Generally class level cascade mode, Stop, is helpful if we just want to know one validation error at a time.
Global Settings for Cascade Modes
In fluent validation 11 and newer versions, there are two more global settings. Instead of setting the same cascade mode inside each and every validator, we can use these global settings and they will be automatically applied to all the validators.
ValidatorOptions.Global.DefaultClassLevelCascadeMode = CascadeMode.Continue;
ValidatorOptions.Global.DefaultRuleLevelCascadeMode = CascadeMode.Stop;
That’s it for this article. I hope you find this information helpful. Let me know your thoughts.