I have been writing only about fluent validation in past few articles. There will be 2-3 articles more about fluent validation. Below is the list of all previous articles in this series and if you want you can go through these articles:
- 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
- ASP .NET Core API – Fluent Validations – Cascade Behaviour
- Demo – Inheritance Validation using Fluent Validations
- ASP .NET Core API – Conditions in Fluent Validations
- ASP .NET Core API – Fluent Validations Based On Database Data
Till now, we have seen what are rules and how various validations can be grouped together under rules in the validator class. In this article, we are going to see how to group the validation rules together and how to rule sets.
What is a RuleSet ?
We have seen that we can use
RuleFor method to specify validation rules for a given property in a type that is being validated. We also know that the validator is tied to a type / model which is being validated. This type needs to be specified while defining the validator class (e.g.
Many times, a single model may be used for various API endpoints. And although the model is same and it has all the same properties, the validation requirements may be different for each endpoint. As the abstract validator is same for the model, how are we going to write the validation rules ?
One , brute force approach, is to create separate model (type) for each endpoint, thus validators would be different and hence we can specify different rules in each validator.
Another option is we can add addition property to know which endpoint is getting called and then use conditional logic to specify the rules using
One additional way is to specify the ruleset. A ruleset allows to combine rules together. Then while triggering the validation, we can specify which ruleset should be triggered while ignoring the rest of the ruleset.
How to define a RuleSet ?
A ruleset can be defined by using
RuleSet method. This method takes a string as parameter, which is name of the RuleSet. Then it takes a function as parameter which is basically to specify the rules.
Let’s take an example. Let’s say we have an entity,
Student. It has properties –
Version, here Id is basically to uniquely identify the record. For calling AddStudent endpoint, id should be always zero, but for calling UpdateStudent endpoint, id should not be zero.
Version property is supposed to be used in update endpoint. It is to avoid overwriting more recent version of the record. So, Version should be non-zero while calling update endpoint and it should be zero while calling Add endpoint.
So, we can create two RuleSets, one for Add endpoint and another for Update endpoint, as shown in the code snippet given below.
How to Validate using Specific RuleSet ?
Now, in the API project, let’s add a StudentController and it should have two endpoint
- One POST endpoint, to add the student, which will trigger “Add” ruleset
- The other PUT endpoint, to update the student record, which should trigger “Update” ruleset.
The question is, how to trigger the validation and guide it to use only specific ruleset ?
Validate method (or
ValidateAsync method) has multiple overloads. One of the overloads take
ValidatorOptions as input. This object has a method
IncludeRuleSets, which takes multiple strings as input parameter. Here we can specify RuleSet name (or names if we want to trigger multiple rulesets together).
It also gives a method to trigger all the rule sets from the validator, by calling
IncludeRuleSets("*") or by calling
The code given below shows the
StudentController, which has two endpoints. Please note that we have called only single
RuleSet from each method, but we can also instruct to trigger multiple
RuleSet while triggering the validation.
Now if we run the application and trigger the Add and Update endpoints, we can see that only the specified RuleSets are getting triggered.
I hope you find this information helpful. Let me know your thoughts.