Monthly Archives: July 2014

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:

[Validator(typeof(UserValidator))]
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()
{
	AreaRegistration.RegisterAllAreas();
	GlobalConfiguration.Configure(WebApiConfig.Register);
	FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
	RouteConfig.RegisterRoutes(RouteTable.Routes);
	BundleConfig.RegisterBundles(BundleTable.Bundles);

	// configure FluentValidation model validator provider
	FluentValidationModelValidatorProvider.Configure(GlobalConfiguration.Configuration);
}

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.

Tags: Filled Under: Programming Posted on: July 15, 2014