Click here to Skip to main content
14,035,164 members
Click here to Skip to main content
Add your own
alternative version


60 bookmarked
Posted 17 Jun 2007
Licenced CPOL

Image Verifier - Custom Control in ASP.NET

, 5 Nov 2007
Rate this:
Please Sign up or sign in to vote.
An article on how to create a custom control to render dynamic images with random text content which can be used for code verification.

Screenshot - main.jpg


This article describes how to create a custom control in ASP.NET for implementing image verification functionality. What is image verification? You might have seen this implemented in many websites like,,, etc., during the signup process. It's simply used for verifying the user's input, by validating the code which the user enters against a random code displayed as image in the form. This helps the application to identify automated submission of forms and reject such requests which could even crash the web site by inputting bulk data to the site.


I saw this functionality implemented in various sites and thought of implementing it while creating a personal website. When I started implementing the functionality in my site, I faced a few issues. Some of them generated random text, persisting the text so that it can be verified against the user input code during post backs, avoid storing the generated code in viewstate or URLs etc. Gradually I found solutions to these issues. I will be explaining those solutions in the sections below.

Key Points

Explaining every piece of code used in the sample application is difficult to do in this article. Hence I will explain the following key steps involved in the development of this custom control.

  1. Create a custom control capable of rendering <img> tags.
  2. Generate a random text, persist it, and render it as image.
  3. Verify the user input against the persisted random text.

Create a custom control to render <Img> tags

First of all, we need to create a custom control which can render the standard HTML <img> tags. It should also generate a dynamic URL and attach it to the src attribute of the <img> tag generated.

This is done in the example by deriving a class named ImageVerifier from WebControl, as shown below.

namespace NatsNet.Web.UI.Controls 
    [DefaultProperty("Text")] [ToolboxData(
       "<{0}:ImageVerifier runat="server">")]  

    public class ImageVerifier : WebControl, IHttpHandler 
        private string m_UniqueID = string.Empty; 
        public ImageVerifier(): base(HtmlTextWriterTag.Img) { } 
        private string MyUniqueID  { ... } 
        public string Text { ... }         
        private string GetRandomText() { ... } 
        protected override void OnInit(EventArgs e) { ... }         
        protected override void LoadControlState(object savedState) { ... }         
        protected override object SaveControlState() { ... }         
        protected override void Render(HtmlTextWriter output) { ... } 

        public void ProcessRequest(HtmlTextContext context) { ... }         
        public bool IsReusable { ... } 

In addition to deriving the control from WebControl, I have implemented IHttpHandler too in that class. This is for making the control render the image itself in addition to the normal <img> tag rendering.

The rendering of the control happens inside the Render method.

protected override void Render(HtmlTextWriter output)
                "ImageVerifier.axd?uid=" + this.MyUniqueID);
    output.Write("<script language="'javascript'">");
    output.Write("function RefreshImageVerifier(id,srcname)");
    output.Write("{ var elm = document.getElementById(id);");
    output.Write("  var dt = new Date();");
    output.Write("  elm.src=srcname + '&ts=' + dt;");
    output.Write("  return false;");
    output.Write(" <a href='#' onclick=\"return RefreshImageVerifier('"
        + this.ClientID + "','ImageVerifier.axd?&uid="
        + this.MyUniqueID + "');\">Refresh</a>");

The first line in the Render method assigns the src attribute for the rendered <img> tag. It generates the URL in the format "ImageVerifier.axd?uid=" + this.MyUniqueID. The control has a property MyUniqueID which will be a unique GUID generated for each control instance. The last line of the Render method outputs a hyperlink to refresh the image without postback.

Generate a random text, persist it, and render it as image

For rendering a dynamic text as the image of this control, we will be using the same class ImageVerifier through the implementation of the IHttpHandler method public void ProcessRequest(HttpContext context). This method will be called when the browser requests the URL specified in the src attribute of the <img> tag rendered. In order to make this happen, we need to configure our ImageVerifier class as an HTTPHandler for URLs like ImageVerifier.axd in the web.config file of the consuming application.




        type="NatsNet.Web.UI.Controls.ImageVerifier, NatsNet.Web.UI.Controls"


Shown below is the implementation of the ProcessRequest() method:

public void ProcessRequest(HttpContext context)
    Bitmap bmp = new Bitmap(180, 40);
    Graphics g = Graphics.FromImage(bmp);
    string randString = GetRandomText();
    string myUID = context.Request["uid"].ToString();

    if (context.Cache[myUID] == null)
        context.Cache.Add(  myUID, 
        context.Cache[myUID] = randString;
    g.FillRectangle(Brushes.WhiteSmoke,0, 0, 180, 40);    
    g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.Default;
    g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
    Random rand = new Random();    
    for (int i = 0; i < randString.Length; i++)
        Font drawFont = new Font("Arial", 18,
            FontStyle.Italic | (rand.Next() % 2 == 0 ? 
            FontStyle.Bold : FontStyle.Regular));
        g.DrawString(randString.Substring(i,1), drawFont, 
            Brushes.Black, i * 35 + 10, rand.Next()% 12);

        Point[] pt = new Point[15];
        for (inti = 0; i < 15; i++)
            pt[i] = newPoint(rand.Next() % 180, rand.Next() % 35);
            g.DrawEllipse(Pens.LightSteelBlue,pt[i].X, pt[i].Y, 
                          rand.Next() % 30 + 1, rand.Next() % 30 + 1);
        context.Response.ContentType = "image/jpeg";
        bmp.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);        

In the ProcessRequest() method, a random text is generated using the private method GetRandomText() and is persisted using the Cache object as shown above. The value of the query string uid will be used as the key for persisting the random text in the Cache object.

For generating random text of a specific length, we can write custom logic. Here in the sample, I have used the Random class to generate random numbers and convert them to the corresponding characters. The same logic can be implemented in different ways as you wish.

private string GetRandomText()
    string uniqueID = Guid.NewGuid().ToString();
    string randString = "";
    for (int i = 0, j = 0; i < uniqueID.Length && j < 5; i++)
        char l_ch = uniqueID.ToCharArray()[i];
        if ((l_ch >= 'A' && l_ch <= 'Z') || (l_ch >= 'a' && 
                l_ch <= 'z') || (l_ch >=  '0' && l_ch <= '9'))
            randString += l_ch;
    return randString;

Verify user input against the persisted random text

Finally, we need to validate the user input against the random text which is displayed as the image. For this, I have added a Text property for our user control. This property retrieves the random text stored in the Cache and returns it. We can use this value to verify the user input.

public string Text
        return string.Format("{0}",

The code below shows an example of the code to be implemented in the consuming application for verifying the user input.

protected void btnSubmit_Click(object sender, EventArgs e)
    if (txtImgVerifyText.Text == ImageVerifier1.Text)
        // User has input the correct text so can continue
        // processing the request.
        // Either user has input an incorrect value or the request
        // is not generated by the manual input. So do not continue
        // processing the request.

Points of interest

In this article, I explained how to use the concept of image verification to help applications in identifying automated submission of forms. The implementation of this image verification used a few coding concepts such as HTTPHandlers, Random class, Cache object, etc.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Nate K
United States United States
Nate has been in the IT industry for more than a decade.

He loves music and listens to all kinds of good music.

You may also be interested in...

Comments and Discussions

GeneralHow can i incorporate the Image Verifier in IIS 7.5. Pin
ashley_h123-Apr-11 5:12
memberashley_h123-Apr-11 5:12 
Generalhi Pin
sathishmarappan127-Feb-11 17:47
membersathishmarappan127-Feb-11 17:47 
GeneralMy vote of 5 Pin
Meetesh Patel19-Jan-11 13:18
memberMeetesh Patel19-Jan-11 13:18 
Generalit does not work on my live project Pin
Nilesh Ahir7-Jan-10 1:42
memberNilesh Ahir7-Jan-10 1:42 
Generalproblem while uploading it.. Pin
Sandeepkumar Ramani16-Nov-09 6:17
memberSandeepkumar Ramani16-Nov-09 6:17 
GeneralRe: problem while uploading it.. Pin
Nilesh Ahir7-Jan-10 1:38
memberNilesh Ahir7-Jan-10 1:38 
GeneralRe: problem while uploading it.. Pin
Sandeepkumar Ramani7-Jan-10 1:49
memberSandeepkumar Ramani7-Jan-10 1:49 
Questioncan i use it in my project Pin
Sandeepkumar Ramani29-Oct-09 4:01
memberSandeepkumar Ramani29-Oct-09 4:01 
GeneralI need the material on custom control Pin
jolly mishra27-Aug-09 19:45
memberjolly mishra27-Aug-09 19:45 
Questiondoes it work in IIS 7.0? Pin
Mudasser Hassan11-Aug-09 6:17
memberMudasser Hassan11-Aug-09 6:17 
AnswerRe: does it work in IIS 7.0? Pin
Member 784911217-Apr-11 7:05
memberMember 784911217-Apr-11 7:05 
GeneralRe: does it work in IIS 7.0? Pin
Andreas Michaelou19-Apr-11 0:14
memberAndreas Michaelou19-Apr-11 0:14 
GeneralRe: does it work in IIS 7.0? Pin
umeshshah19-Apr-11 0:23
memberumeshshah19-Apr-11 0:23 
Questionhow to maintain the persistance using saveviewstate and loadview state methods Pin
anithacute5-Apr-09 21:14
memberanithacute5-Apr-09 21:14 
GeneralSome suggestions for improvement Pin
kabwla27-Mar-09 4:15
memberkabwla27-Mar-09 4:15 
QuestionHow can I use it in a web application? Pin
amir asaraf16-Nov-08 6:00
memberamir asaraf16-Nov-08 6:00 
AnswerRe: How can I use it in a web application? Pin
kabwla27-Mar-09 4:12
memberkabwla27-Mar-09 4:12 
GeneralHi Pin
manu_1229-Nov-07 20:12
membermanu_1229-Nov-07 20:12 
GeneralGood work, a little bug Pin
Johnjames11-Nov-07 7:21
memberJohnjames11-Nov-07 7:21 
GeneralGood Job Pin
merlin9816-Nov-07 4:22
professionalmerlin9816-Nov-07 4:22 
QuestionIs it strong? Pin
Dmitry Salko5-Nov-07 10:05
memberDmitry Salko5-Nov-07 10:05 
AnswerRe: Is it strong? Pin
Nate K11-Nov-07 12:13
memberNate K11-Nov-07 12:13 
QuestionHi Pin
phuhoa4-Nov-07 16:21
memberphuhoa4-Nov-07 16:21 
AnswerRe: Hi Pin
Nate K5-Nov-07 8:30
memberNate K5-Nov-07 8:30 
Questionscript question Pin
kostasvel6-Sep-07 7:13
memberkostasvel6-Sep-07 7:13 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web01 | 2.8.190424.1 | Last Updated 5 Nov 2007
Article Copyright 2007 by Nate K
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid