Fluent Validation and RuleSets
Fluent Validation and RuleSets

ASP .NET Core API – Fluent Validation RuleSets

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:

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. AbstractValidator<StudentModel>)

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 When method.

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 – Id, Name, and 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.

The 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 IncludeAllRuleSets.

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.

Leave a ReplyCancel reply