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:
The response is an HTTP 400 indicating that validation failed. Trying again with a correctly formatted email address returns a successful HTTP status code:
Here, validation of the User object was successful and an HTTP 200 was returned from the API controller indicating success.
Tags: WebAPI Filled Under: Programming Posted on: July 15, 2014
Jeff Pinkham
August 14, 2014 at 1:55 pm
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.