Thursday, April 2, 2015

Web Api Request Validation Made Easy

Intro

Validating inputs into your system can be quite a chore. Field X might be a required field, Field Y might need to be email format, Field Z might need to be a number between 1-100. Coding such requirements isn't very difficult, just tedious. Wouldn't it be great if there was something that would lessen the monotony? Yeah, you know where I'm headed...there is such a beast, and we can bask in its magnificence!

Note: I'll be using Visual Studio 2013 Community Edition and Fiddler to do my work.


Sample

For starters, create a new Web Api application. I've created such a solution and named it BlogWebApiValidation. Add a new controller to it named ValidationController.


 Now add a new class to your Models folder named ValidationSampleRequest. It'll have just three properties, so it'll be pretty simple. Here it is:

using System.ComponentModel.DataAnnotations;

namespace BlogWebApiValidation.Models
{
    public class ValidationSampleRequest
    {
        [Required]
        public string RequiredString { get; set; }

        [EmailAddress]
        public string SomeEmail { get; set; }

        [Range(1, 100)]
        public byte SomeNum1To100 { get; set; }
    }
}

Now go back to your ValidationController class. It doesn't need to do much, it just needs a single method named Post that accepts an object of type ValidationSampleRequest. Here's what yours might look like:

using System.Web.Http;
using BlogWebApiValidation.Models;

namespace BlogWebApiValidation.Controllers
{
    public class ValidationController : ApiController
    {
        public IHttpActionResult Post(ValidationSampleRequest request)
        {
            if (ModelState.IsValid)
                return Ok();
            else
                return BadRequest(ModelState);
        }
    }
}


This Post method is pretty bare-bones, as we're just demonstrating model validation. All it does is check the validity of the ModelState (the request), and returns a 200 OK HTTP result if good, and a 400 Bad Request HTTP result if bad. Simple! Go ahead and run the project. You'll get a 403 Forbidden error in your browser but that's OK. Our testing involves something a little more complex than just firing up a browser window. But hey, leave the browser window open :)

Fire up Fiddler and let's play with this sucker. I'll skip some of the explanations and just show you real quick how to use Fiddler to test your Web APIs. There's a lot more to it than what I'll cover, I just want to demonstrate the API for now. Anyways, launch Fiddler. You can install it from the link below if you don't already have it.

First, click on the "File" menu, and click on the "Capture Traffic" menu item. This will tell Fiddler not to capture everything you're doing on the internet. That's too much noise for us to sift through.

Now click on the Composer tab. This brings you to a window where you can create your own requests. Select "POST" as the verb, and type in the URL of your web api controller. You can see mine below, though yours (especially the port) may be slightly different. In the headers field right below the URL you can just copy what I have. In the Request Body field, you can also copy what I have below.

Headers:
User-Agent: Fiddler
Accept: application/json
Content-Type: application/json

Request Body:
{
"RequiredString": null,
"SomeEmail": "not an email",
"SomeNum1To100": 101
}


Now hit the big Execute button. You'll see you now have a single request shown in the left-hand side of the window, and it should have a 400 result. Double-click this response record, then on the right-hand side of the window click on the "Raw" button. If you look down there in the response section it now shows you the raw HTTP response.

2 key points here:
  1. You received 400 Bad Request response. Poifect!
  2. The body of the response contains a JSON object which has details on what precisely went wrong. What good is model validation if the client doesn't know what they did wrong? If you keep scrolling to the right you can see that all 3 fields failed validation.


What's Next?

Validation has a lot more options like regular expressions, you can use nullable types like bool? to make a normally non-nullable field required, it will validate sub-objects in complex requests, credit cards, comparison of 2 properties, you can even create your own custom class validation methods, custom error messages, and much much more.

Fiddler also has a lot more options than what I breezed on through. Play around with it, it's great for testing Web API's.

Resources

Fiddler 
DataAnnotations (more validation options)

1 comment:

  1. Excellent article Pete! Really takes all the legacy wrenching of the nuts and bolts out of validation and makes it a breeze.

    ReplyDelete