NET Core Complex properties Validation — using FluentValidation

Photo by Scott Webb on Unsplash

Model validation is critical for application persistency and data integrity. validating your models before inserting them into the database is second nature for a well-thought-out application.

Today, I will be walking you through validating complex property types using FluentValdiation.

What should you know before we start

1-NET Core
2-Net Core API
3-C#

Disclaimer:
I will not be focusing on the structure of the application but rather, I’m more focusing on the technology we’re working with (FluentValdiation framework).

1-Adding the models.

I have created a .netStandard library for my domain models

  • TestInfo
  • TestTaker

That’s all we need for our Domain Library Project.

2-Adding the Validation classes.

I have created a .netStandard library for my application logic

-Before adding the validation classes we will need to add references to a couple of packages to enable the FluentValdiation features.

Once the packages have been added, I have made a folder named “Validations” and in there I have added to classes (TestInfoValidator, TestTakerValidator).

  • TestInfoValidator
  • TestTakerValidator

As you can see, both of these classes inherit from AbstractValdiator class. this class is the base class for the validation. In the constructor, we specify our rules for each property. you can chain properties (look at FirstName and date of birth property in TesTakerValdiator.). Also, you can have custom functions to validate simple or complex child properties. SInce TestTaker has a TestIOnof property we can reference the testInfo validator classes from TesTakerValdiator, that’s great right!!. This way, you can reference different validators for nested properties. this way you element all the data annotation that makes the model class look messy and cluttered.

3-Adding the service Interface

In the FluentApplicationService.Application project I have added a new folder named “Services.” this will deal with our creation and modification of the TestTaker entity.

4-Adding custom exceptions to .Application project

This class has a constructor that accepts ValidationResult as a parameter (this will come from the validation result by FluentValdiation framework).

5-Adding concrete implementation of the service.

I have added a new .netStandard library project. named FluentApplicationService.Persistence.

  • Related Packages

I’m having the actual implementation of the TestService in a different project for looser coupling in the application.

As you can see, I try to validate the property and if there are any errors it will throw our custom exception we have implemented in the .Application Project.

  • Specifying our Dependencies

I have created a static class to inject the dependencies we have.
In this project, we have a dependency between ITestService and TestService.

6-Creating a simple API project to test the application.

I have created an API project to test the creation and modification of the model.

  • Resolving the dependencies in Startup.cs

We have added the dependencies we have specified in the .Persistence project.

  • Adding Middleware for our custom exception.

The custom exception we have added cannot be automatically converted to HTTPS errors/exceptions so we need middleware to resolve the errors and provide something more meaningful as a response.

What’s happening here is, every time we have an invocation on one of our API Endpoints it will go through this middleware and try to provide a response if there are no exceptions, and if there is any, it will try to map out the corresponding error based on the exception type and it will write the errors as a JSON string if there is any.

  • Adding the middleware extension class

This static class will add the ExceptionHandlerMiddleWare as a middleware component in the IApplicationBuilder.

  • Adding the middleware to our configuration method.
  • TestTakerController

This is the API controller where the methods are implemented.

As you can see it’s a very lightweight controller since we have dealt with our exceptions using middleware, and we specified our Response types on top of each method.

Now you can test this by using an API testing tool (Postman etc.. ).

Conclusion

Photo by John Salvino on Unsplash

There are many tools and ways to validate your application's domain models. this was one of many ways you can use to validate your data. we have only scratched the surface with the FluentValdation framework.

you can look at much more complex validations under the FluentValidation documentation.

Full GitHub solution