This article explains how to create a CAPTCHA image using a generic handler.

Required Tools

  • Visual Studio
  • SQL Server 2005

Step 1
Create a new solution and add an empty web project.

Step 2
Add a generic handler page (.ashx).

Step 3
Replace the ProcessRequest method implementation with the following code.
<%@ WebHandler Language="C#" Class="ghCaptcha" %>

using System;
using System.Web;
using System.IO;
using System.Web.SessionState;
using System.Drawing;
using System.Drawing.Imaging;

public class ghCaptcha : IHttpHandler, IReadOnlySessionState
{
    public void ProcessRequest(HttpContext context)
    {
        MemoryStream memStream = new MemoryStream();
        string phrase = Convert.ToString(context.Session["Captcha"]);

        //Generate an image from the text stored in session
        Bitmap CaptchaImg = new Bitmap(180, 60);
        Graphics Graphic = Graphics.FromImage(CaptchaImg);
        Graphic.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;

        //Set height and width of captcha image
        Graphic.FillRectangle(new SolidBrush(Color.Blue), 0, 0, 180, 60);
        Graphic.DrawString(phrase, new Font("Calibri", 30), new SolidBrush(Color.White), 15, 15);
        CaptchaImg.Save(memStream, System.Drawing.Imaging.ImageFormat.Jpeg);
        byte[] imgBytes = memStream.GetBuffer();

        Graphic.Dispose();
        CaptchaImg.Dispose();
        memStream.Close();

        //write image
        context.Response.ContentType = "image/jpeg";
        context.Response.BinaryWrite(imgBytes);
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}


Step 4
Build the page and resolve the namespace.
Since the .ashx is a generic handler, it processes HTTP requests and doesn't write session values. So we need to inherit the class with IReadOnlySessionState as in the following.

The following namespaces are used.
using System;
using System.Web;
using System.IO;
using System.Web.SessionState;
using System.Drawing;
using System.Drawing.Imaging;


Step 5
Prepare the Login page; add a new page named Login. aspx and add the following .aspx script.
<form id="form1" runat="server">
    <h1>
        Login</h1>
    <table id="tblLogin" width="40%" border="0" cellpadding="0" cellspacing="4" style="background-color: #cecece;"
        align="center">
        <tbody>
            <tr>
                <td align="center">
                    <asp:Label ID="lblError" runat="server"></asp:Label>
                </td>
            </tr>
            <tr>
                <td width="30%" align="right">
                    User ID :
                </td>
                <td width="70%">
                    <asp:TextBox ID="txtLogin" runat="server" Width="175px" MaxLength="20" AutoCompleteType="Disabled"></asp:TextBox>
                </td>
            </tr>
            <tr>
                <td align="right">
                    Password :
                </td>
                <td>
                    <asp:TextBox ID="txtPassword" runat="server" Width="175px" MaxLength="20" AutoCompleteType="Disabled"
                        TextMode="Password"></asp:TextBox>
                </td>
            </tr>
            <tr>
                <td>
                </td>
                <td colspan="2" align="left">
                    <div>
                        <asp:Image ImageUrl="ghCaptcha.ashx" runat="server" ID="imgCaptcha" />
                    </div>
                </td>
            </tr>
            <tr>
                <td align="right">
                    Enter Code :
                </td>
                <td>
                    <asp:TextBox ID="txtCode" runat="server" Width="175px" MaxLength="5" AutoCompleteType="Disabled"></asp:TextBox>
                </td>
            </tr>
            <tr>
                <td colspan="2" align="center">
                    <asp:Button ID="btnLogin" runat="server" Text="Login" />
                </td>
            </tr>
        </tbody>
    </table>
    </form>


The page has the following controls:

Assign an ImageUrl property of an Image control as Path of the ghCaptcha.ashx file.

Step 6

The following is the code behind Login.aspx.cs.
#region " [ using ] "
using System;
using System.Web.UI;
#endregion

public partial class Login : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            UpdateCaptchaText();
        }
    }

    #region " [ Button Event ] "
    protected void btnRefresh_Click(object sender, ImageClickEventArgs e)
    {
        UpdateCaptchaText();
    }


    protected void btnLogin_Click(object sender, EventArgs e)
    {

    }
    #endregion
    #region " [ Private Function ] "
    private void UpdateCaptchaText()
    {
        txtCode.Text = string.Empty;
        Random randNum = new Random();

        //Store the captcha text in session to validate
        Session["Captcha"] = randNum.Next(10000, 99999).ToString();
        imgCaptcha.ImageUrl = "~/ghCaptcha.ashx?" + Session["Captcha"];
    }
    #endregion
}

The value of Session["Captcha"] is updated in the Page_Load event of Login.aspx.cs and is accessed in the handler page and session code used to generate the CAPTCHA image.

Step 7

Build and run it.
The Login Page Visuals os as below.

Step 8
The following are enhancements (included in the source code download).
A Refresh button beside the CAPTCHA image for changing the CAPTCHA without a page postback


Page validation

HostForLIFE.eu ASP.NET Core Hosting

European best, cheap and reliable ASP.NET hosting with instant activation. HostForLIFE.eu is #1 Recommended Windows and ASP.NET hosting in European Continent. With 99.99% Uptime Guaranteed of Relibility, Stability and Performace. HostForLIFE.eu security team is constantly monitoring the entire network for unusual behaviour. We deliver hosting solution including Shared hosting, Cloud hosting, Reseller hosting, Dedicated Servers, and IT as Service for companies of all size.