IValidatableObject Interface – Custom Validations in .NET Core

IValidatableObject Interface – Custom Validations in .NET Core

.Net ecosystem provides us a way to create custom validations using IValidatableObject Interface. Let’s see it in action in a .Net Core 3.1 MVC project.

Getting Started

Let us create a sample .NET Core 3.1 MVC project, add a new controller named as PersonController and a PersonViewModel to populate a view.

The PersonViewModel contains very basic properties Name, Gender, City and Orders. These have been decorated with Required data annotations currently to throw the mandatory validations.

Let’s create the view to display the UI, and run the project to see how the page looks.

Post method

I have an input type=”submit” button which will post the form to the Index POST method. Let us create the POST method.

This POST method will validate the incoming model as per the Required data annotations applied. Let’s see that in action and then we would continue to introduce the IValidatableObject Interface.

Start the app, browse to /Person/Index, click on Submit without entering any information. The validation errors should be displayed onto the relevant span tags.

Adding IValidatableObject Interface

Let us add the IValidatableObject Interface and set up few custom validations.

MSDN says that “Instances of types that implement this interface can be checked to determine if they are valid.”

We inherit the PersonViewModel class with the IValidatableObject interface as follows:

We need to implement the interface’s only method in the child model.

The method validate returns a collection of ValidationResult objects. We use the below constructor of the ValidationResult to create the custom validation objects. The first parameter is the error message which we want to display, the second parameter is the IEnumerable of member names underneath whom we want to display the error message.

In our scenario, the first custom validation says that if the Order value is less than 10 or greater than 100, then raise a validation error message that “Orders are messed up”. The 2nd custom validation says that if the Name doesn’t contain the string “an”, throw a validation error message saying that “Name is not proper.”.

These error messages are not ideal, these are just to demonstrate that how powerful is the interface and we can construct our own custom validations of any sort.

An important point to note is that the custom validations raised by the IValidatableObject are fired when the data annotations validation conditions have been satisfied, i.e. in the above scenario the custom validations will only be fired if all the Required validations of the model are satisfied.

It is by design – the property validations need to be pass first, otherwise it may be possible that the model object itself is incomplete.

Let us fill all the mandatory fields, but enter the name as “John” and Orders as “1000”. Once we click the Submit button, the custom validations will kick in and display.

Another iteration:

We can also display a single custom validation on more than 1 input member, because the overload which we use lets us use an IEnumerable. Let’s see that in action.

The validation message appears underneath both the Name and City fields.

In a nutshell, IValidatableObject is very powerful, helps us to construct different types of custom error messages.

The project code can be found out at:

https://dev.azure.com/anuragsinha10/ServerSidevalidations/_git/ServerSidevalidations

Did you find this article valuable?

Support Anurag Sinha by becoming a sponsor. Any amount is appreciated!