FluentValidation With WebAPI 2

The GitHub project description for FluentValidation is succinct and explains what it does better than I could paraphrase:

A small validation library for .NET that uses a fluent interface and lambda expressions for building validation rules for your business objects. 

This is a great open-source library that I’ve been using for years.  One of the things that makes this a great library is its constantly evolving.  Support for the ever-increasing versions of ASP.NET MVC have been kept up to date.  Until recently there was no official support for ASP.NET WebAPI, but that too has changed.

WebAPI 2 support has been released, however the official documentation on CodePlex hasn’t yet been updated to reflect that.  Luckily the documentation for FluentValidation’s ASP.NET MVC integration is there because it’s a good starting point.  However, instead of working with an MVC controller, let’s work with an ApiController.

First, here is a User object and our User validator class:

public class User
	public int Id { get; set; }
	public string Email { get; set; }
	public string FirstName { get; set; }
	public string LastName { get; set; }

public class UserValidator : AbstractValidator<User>
	public UserValidator()
		RuleFor(x => x.Id).NotNull();
		RuleFor(x => x.Email).EmailAddress();

The validation rules defined above state that a User object can’t have a null Id and the EmailAddress must be a valid email.  Next, create an API controller.  Here is a POST method that will validate the ModelState.  If validation fails, an HttpResponseException will be thrown.  If validation is successful, you would do whatever processing you need (insert/update/etc) and then return a response.

public class UserController : ApiController
	public HttpResponseMessage Post(User user)
		if (!ModelState.IsValid)
			// validation failed; throw HttpResponseException
			throw new HttpResponseException(
				new HttpResponseMessage
						StatusCode = HttpStatusCode.BadRequest,
						ReasonPhrase = "Validation failed."

		// validation passed; process record and return success
		return this.Request.CreateResponse(HttpStatusCode.OK);

Now that the validator is defined and there’s an API controller, how does WebAPI know to process the validation for the API method’s ModelState?  In the Global.asax’s Application_Start event, the FluentValidationModelValidateProvider needs to be configured (line 10):

protected void Application_Start()

	// configure FluentValidation model validator provider

If the FluentValidationModelValidateProvider isn’t configured, all ModelState validation checks would return an IsValid value of true, even if validation rules were not met.

Let’s see this in action.  Here is a request that contains an invalid formatted email address:

Invalid HTTP request.
HTTP request with an invalid email address that doesn’t pass validation.

The response is an HTTP 400 indicating that validation failed.  Trying again with a correctly formatted email address returns a successful HTTP status code:

Valid HTTP request
HTTP request with a valid User model passes validation.

Here, validation of the User object was successful and an HTTP 200 was returned from the API controller indicating success.

6 Replies to “FluentValidation With WebAPI 2”

  1. Thanks for posting this, finally got the web api 2 fluent validation to work.. Now I need to figure out a way to nicely return the validation errors and map them to angular form fields.

  2. I’m probably missing something because I can’t hook the validations to work even after setting up the provider: FluentValidationModelValidatorProvider.Configure(GlobalConfiguration.Configuration);

  3. make sure you use the reference System.Web.Http.Validation, instead of System.Web.Mvc.Validation

    Add following lines in global asasx to register the FluentValidator
    var provider = new FluentValidationModelValidatorProvider(Creator.RootContainer.Resolve());
    GlobalConfiguration.Configuration.Services.Replace(typeof(IBodyModelValidator), new FluentValidationBodyModelValidator());
    GlobalConfiguration.Configuration.Services.Add(typeof(ModelValidatorProvider), provider);

Leave a Reply

Your email address will not be published.