Conditions in Fluent Validation
Conditions in Fluent Validation

ASP .NET Core API – Conditions in Fluent Validations

Many times, in real world applications, the input validation is not straight forward. Sometimes the validation rules may change depending on certain conditions. In this article, we are going to discuss about how to apply conditions on validation logic written using Fluent Validation.

Before we begin !

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:

What do we need to validate ?

Let’s say we have an API to store information about customers. A customer can be an individual person or an organization. When the customer is individual person, first name and last name properties are required to be filled in. On the other hand, when the customer is an organization, the organization name needs to be filled in.

Let’s say we have a single class to represent both types of customers. The class has a Boolean property, isOrganization. If this is set to true, it means the request contains organization’s information. Otherwise the request is supposed to contain individual’s information.

The code snippet for this type is given below. The code snippet also contains definition of the controller endpoint, which accepts this type as input parameter.

How to apply conditional validation ?

There are multiple ways in which conditions can be applied in fluent validation validators. First option is to add call to the When method. The When method takes an expression or a method which will return a Boolean value. If the returned value is true, then the immediately preceding validation is applied, otherwise the validation is skipped.

Similar to When, there is also an Unless method, which takes an expression or a method as input. That expression or method should return a Boolean Value. If the returned value is false, then the immediately preceding validation is applied, otherwise the validation is skipped.

There are also WhenAsync and UnlessAsync versions available in case the conditional logic to call is asynchronous.

Examples

Let’s take an example. The code given below has two validators specified in a single rule. First rule checks that the value should not be null. Second validator checks that value should not be empty. And then there is a When method call, which has condition to check that IsOrganization should be false.

In this case, the condition specified in the When method is applicable to the only immediate validation, which is NotEmptyValidator. So when IsOrganization is false, first name cannot be empty string. And regardless of value of IsOrganization value, first name is not allowed to null.

RuleFor(x => x.FirstName)
    .NotNull()
    .NotEmpty().When(x => !x.IsOrganization)

This means that if every validation is supposed to be executed only if certain condition is satisfied, the When method should be called on every validator. In the code given above, if we want NotNull validation to be applied only when IsOrganization is false, then we will need to add a When Call after NotNull.

Now, if we do not want to specify same condition multiple times, then we can use top-level When method instead of chaining the When call after every validator. The code snippet given below shows an example of top level When method. As we have condition only on the Boolean property which can have only two states, the alternative validations can be put inside the Otherwise call as shown in the snippet.

We can place as many top level When calls as needed.

I hope you find this information helpful. Let me know your thoughts.

Leave a ReplyCancel reply