Web API powerful Custom Model Validation with FluentValidation

Since DataAnnotations were introduced, developers found an easy way for setting up their database (especially those who use Code First development) while adding at the same time validation logic to their domain objects. In the Web API side, when an object is posted to one of it’s actions, you can check if the object posted is valid with something like this..

While all these sounds great, what happens when you have to add custom validation to your objects? What happens, if you want a User object posted with a FirstName property to be marked as Invalid when it’s first letter is not capital? Can you do this with Attributes? This very question reveals the real problem here, that is it’s not your domain models that needs to be validated but the ViewModel, the one that is transferred between the client and the server. Some times, your ViewModel objects may be the same with your domain objects which is something I always try to avoid. Anyway, I thought it would be good to post about this and make things a little bit clearer for those who are confused.
A clean solution to this problem is to split the logic where you define your database configuration (with DataAnnotation attributes or not) and the logic that validates your ViewModel objects. Here’s what we ‘re gonna see on this post:

Set up the database (Code First development)

Add database configuration using Fluent API

Add custom validation configuration using FluentValidation

For this solution I chose on purpose not to use custom ViewModel objects so that you can see that model validation can be much more things than database configuration. Let’s start.
I created a new black solution in VS 2013 and added three projects:

Domain (Class Library)

Data Access (Class Library)

Web API Empty Web Application with MVC / Web API templates checked

Suppose that we want to create a Registration form so that user can sign up to our application. Starting from the Domain class library project add the following classes.

You can see that I have defined a Gender class which is going to hold only two records, one for Male and another one for Female users. There will be a One to Many relationship between them (not defined yet) and we will declare that SexID will be the User’s foreign key to Gender table.
Switch to the DataAccess project and install Entity Framework using Nuget Packages. Also make sure you add reference to the Domain project. First of all, we need to introduce the Entity Framework our classes. Add a UsersContext class as follow:

To setup Dababase configurations you have two options. The one is to use DataAnnotations and the other is to use Fluent API. I prefer the latter cause I like to keep my domain objects clean. I usually add a “Configurations” folder in the project and setup a specific configuration for each of my domain objects. Do this and add two classes that inherits the EntityTypeConfiguration class as follow:

As you can see these are basic database configurations that will have impact in the way Entity Framework Code First will set the database for us. You need to add those two configurations in the UsersContext class:

While at the same project, you need to set an initializer class that will always re-create our database, seeding two records for the Gender table. On production projects you will propably need migration logic but this is enough for this post.

Now switch to the WebAPI project and for start install Entity Framework through Nuget Packages. Then add references to both of the class library projects. Open Global.asax.cs and add the following line into the Application_Start method, in order to set our database initializer.

Before starting your application you may have to set System.Web.Mvc reference, Copy Local property to True, from the properties window.

Fire your application and invoke /api/users action through your browser. You should see the UsersDB database in your local server as follow:
If you get any errors never mind, you can download this solution from the bottom of this post. We started this post to set custom validations to our object without affecting our database configurations. To check this, create an MVC Controller named HomeController with an Index method.

Right click inside the View and select Add view. This will create an Index.cshtml file. I prefer not to paste all of it’s code here since it’s quite big. I will explain though what I did and what I am posting from this page. You can create your own implementation for this or just open the attached solution at the bottom of this post. I have created a registration form using AngularJS and Bootstrap which simply posts form values to our UsersController post method.
If you write your own implementation just make sure on Create my Account button click event, to post all form values without running any javascript validation. Here is the AngularJS function running when the button is clicked.

It’s time to setup the Validation logic. We saw that the User.Username property has been created from Code First configuration as an [nvarchar(100), not null] property in the database. Hence, if the user selects a username with inapropriate or offensive words, the username of course will be valid and the stored in the database.
What we want to do is to add validation logic so that if certain words found on the usename property, automatically mark the ModelState as invalid. This can be done using the FluentValidation. You can see that we try to inject a model validation logic that has nothing to do with database table properties. Switch to the Domain class library and add a new folder named Validations. Install the FluentValidation package running the following command:

I have highlighted only the validations added for the username. I added some more for other properties so you can study them later. I declared a Rule for the username property which says that userame must not be offensive and if so, return the relative message. You need to attach the validation configuration to the specific object you want to validate, that is the User class. This is the updated version.

Food for thought

The reason I decided not to use custom ViewModel objects is to highlight the opposite: That is validation logic shouln’t necessary depent (only) on domain/entity objects but also in custom ViewModel objects. You can create custom lightweighted ViewModel classes for exchanging data between client and server and only if their ModelState is valid procceed to further processing. This way you prevent useless interaction with your database repository.

What comes next

In the next two 2 posts we will see how to create a full functional SPA application using AngularJS and pure Web API. Make sure you follow this blog in order to get notified when this occurs!

The purpose of this blog is to broaden my education, promote experimentation and enhance my professional development. Albert Einstein once said that “If you can’t explain it simply, you don’t understand it well enough” and I strongly believe him!