Friday, August 12, 2011

Creating and Using a CAPTCHA in ASP.NET MVC

A CAPTCHA is a challenge-response system wherein typically a dynamically generated image consisting of random letters and numbers is displayed to the users and the users are asked to re-enter the text in an attempt to verify that both of them match. Any ASP.NET developer would want to prevent spam and automated form submissions in the website being developed and that is where CAPTCHA is extremely useful. The primary purpose of CAPTCHA is to ensure that data is being submitted by humans and not by an automated software system. CAPTCHA is frequently used in user registration and contact forms to prevent spam and abuse of the facility. In this article you will learn how a simple CAPTCHA system can be developed in ASP.NET MVC.

Basic Steps

Before you delve into further details create a new ASP.NET MVC 3 application with ASPX views. Once created add a new controller named Home into the Controllers folder. You will be adding the required action methods to the Home controller later.

Creating a Custom Action Result

An action result indicates the response from an action method and is represented by System.Web.Mvc.ActionResult class. Though most of the action methods can use ActionResult class as their return value you can also create a custom action result class. In fact, the MVC framework includes several classes that inherit from the ActionResult base class. Many of them are shown in the following figure.
The MVC framework includes several classes
Figure 1: The MVC framework includes several classes

In order to create a CAPTCHA system it is necessary that we emit a dynamically generated image with random text onto the response stream. To meet this requirement you will create a custom Action Result class. The new action result will inherit from ActionResult base class. To create a new action result, add a new class in the Models folder and name it CaptchaImageResult. The following listing shows the empty CaptchaImageResult class.


public class CaptchaImageResult:ActionResult
{
}

Generating Random Strings

The CaptchaImageResult class needs to display random string values consisting of letters and numbers. To generate such random strings you will need to create a method inside the CaptchaImageResult class that does the job for you. The GetCaptchaString() method as shown below is responsible for creating fixed length strings consisting of alpha-numeric values.
public string GetCaptchaString(int length)
{
    int intZero = '0';
    int intNine = '9';
    int intA = 'A';
    int intZ = 'Z';
    int intCount = 0;
    int intRandomNumber = 0;
    string strCaptchaString="";
 
    Random random = new Random(System.DateTime.Now.Millisecond);
 
    while (intCount < length)
    {
        intRandomNumber = random.Next(intZero, intZ);
        if (((intRandomNumber >= intZero) && (intRandomNumber <= intNine) || (intRandomNumber >= intA) && (intRandomNumber <= intZ)))
        {
            strCaptchaString = strCaptchaString + (char)intRandomNumber;
            intCount = intCount + 1;
        }
    }
    return strCaptchaString;
}
As you can see, the GetCaptchaString() method accepts a single parameter - length - that indicates the length of the resultant CAPTCHA string. The four variables intZero, intNine, intA and intZ simply store ASCII values for numbers (0-9) and letters (A-Z). Note that we are using only upper case letters in the above logic. You can, of course, add lower case letters if required. Inside the while loop, Random class is used to generate random numbers between a range of 0-9 and A-Z. The random number obtained from the Random class is converted into a character value and stored in strCaptchaString variable. Finally, the complete CAPTCHA string is returned back.

Outputting an Image Dynamically in the Response Stream

Generating a random string is just one part of the story. More important is to emit this random string as an image in the response stream. Emitting the random string as an image will make it difficult for automated software programs to read the CAPTCHA string from the HTML source. To generate an image dynamically, you need to override ExecuteResult() method of the ActionResult base class. The ExecuteResult() method is responsible for any custom processing that the child class wants to plug-in. The complete ExecuteResult() method is shown below:
public override void ExecuteResult(ControllerContext context)
{
    Bitmap bmp = new Bitmap(100, 30);
    Graphics g = Graphics.FromImage(bmp);
    g.Clear(Color.Navy);
    string randomString = GetCaptchaString(6);
    context.HttpContext.Session["captchastring"] = randomString;
    g.DrawString(randomString, new Font("Courier", 16), new SolidBrush(Color.WhiteSmoke), 2, 2);
    HttpResponseBase response = context.HttpContext.Response;
    response.ContentType = "image/jpeg";
    bmp.Save(response.OutputStream,ImageFormat.Jpeg);
    bmp.Dispose();
}
The ExecuteResult() method has one parameter - ControllerContext - that provides the context information in which the method is being called. For example, the HTTP response stream is accessed using the HttpContext provided by the ControllerContext parameter. The method first creates a Bitmap of size 100 X 30. It then washes it with a Navy background. A random CAPTCHA string with a length of 6 characters is generated by calling the GetCaptchaString() method. This random string is then stored in a Session variable so that you can compare the user input later. The DrawString() method of the Graphics object draws the random string onto the image. The image is then saved onto the response stream in JPEG format.
In the above example, you are using a simplistic approach of generating CAPTCHA images. You can also make use of certain techniques (distorting the characters or emitting two sets of characters for example) that make it even more difficult for the automated software programs to read them.

Showing a CAPTCHA Image on a View

Next, you need to create an action method in the Home controller as shown below:
public CaptchaImageResult ShowCaptchaImage()
{
    return new CaptchaImageResult();
}
The ShowCaptchaImage() method simply returns a new instance of CaptchaImageResult class you created earlier. Note that the MVC framework takes care of calling the ExecuteResult() overridden method for you.
The ShowCaptchaImage() action method is used in the Index view as shown below:

Captcha in ASP.NET MVC

<% using (Html.BeginForm("index", "home")) { %> Please enter the string as shown above: <%= Html.TextBox("CaptchaText")%> <% } %> <%= ViewBag.Message %>
As you can see, the above markup creates an HTML form. Notice how the src attribute of the tag is pointing to the ShowCaptchaImage action method. This way whenever the image is rendered it invokes the ShowCaptchaImage() method and a CAPTCHA image is outputted. The TextBox allows the user to enter the text as seen on the CAPTCHA.
The following figure shows the Index view in action:
The Index View
Figure 2: The Index View

Verifying the CAPTCHA Value

Before you run the Index view, you need to add Index() action methods as shown below:
public ActionResult Index()
{
    ViewBag.Message = "A fresh CAPTCHA image is being displayed!";
    return View();
}
 
[HttpPost]
public ActionResult Index(string CaptchaText)
{
    if (CaptchaText == HttpContext.Session["captchastring"].ToString())
        ViewBag.Message = "CAPTCHA verification successful!";
    else
        ViewBag.Message = "CAPTCHA verification failed!";
 
    return View();
}
The first Index() action method takes care of GET requests whereas the second one takes care of POST requests (as indicated by [HttpPost] attribute). The first Index() method simply puts a Message in the ViewBag and shows the Index view (Figure 2). When the user enters the CAPTCHA value in the TextBox and submits the form, the second Index() action method compares the submitted value with the value stored in the Session earlier (recollect that ExecuteResult() method stores the CAPTCHA text in a session variable). Depending on the outcome of the comparison either a success or failure message is displayed in the view.

Summary

A CAPTCHA is a challenge-response system frequently used to keep away spammers and automated software programs from web pages accepting data from the end users. Common examples of such pages include user registration forms and contact forms. In order to create your own CAPTCHA system in ASP.NET MVC you create a custom ActionResult class that generates a random string value and then emits it as an image on the response stream. You can add more features to the CAPTCHA you developed in this article to make it more difficult for automated software programs to read the CAPTCHA text.