The Ultimate CAPTCHA Custom Server Control

Download Source to this article

Author: Peter Kellner, 73rd Street Associates
Date: August 20, 2006
Location: San Jose, California USA
Topic: Custom Server Control for CAPTCHA, Part 1 Usage


CAPTCHA stands for (Completely Automated Public Turing test to tell Computers and Humans Apart). The technology was originally developed at Carnegy Mellon University to help tell the difference between a human entering data into a computer system and a machine. The process typically involves showing the user a distorted picture of text and numbers, then the user must interpret this, type what they see into a text field and the computer checks for correctness. Below is a picture of a typical CAPTCHA expression. Wikipedia has a nice definition for CAPTCHA here.

Typical Captcha Image


In this article, the basic usage of a CAPTCHA custom server control will be discussed. This control is for use in ASP.NET 2.0 only. It is provided in source as well as executable form which means you can use it in your app_code or bin directly. If you use the DLL version, it will support drag and drop from the Visual Studio 2005 Toolbox. The control supports templates which means you can customize it to work in your application giving a consistent look and feel.

Below are two representations of the use of the CAPTCHA custom server control. One is simply using the control in it’s default configuration with no template, and the other is after modifying the controls template with extra contact information.

Simple Usage Scenario

Assuming you have installed the Ultimate CAPTCHA control correctly, you will see in your Visual Studio 2005 Toolbox the CAPTCHA Control. Below is a screen shot of this.

Notice the first entry in the toolbox is the CaptchaUltimateControl. This control was placed on the work surface by dragging and dropping it. What you are seeing is the default control with no template (we will learn more about that later). Then, after the control is dropped on the work surface, you can select it and you will see a list of properties in the properties dialog. These properties can be changed and the control will dynamically update on your work surface. Below is a more detailed list of the properties you can set and what they mean.

There are several properties that are not quite self explanatory. Those are detailed below:

CaptchaLength: This is the number of characters to be displayed in the CAPTCHA message

CaptchaType: There are two types of CAPTCHA that can be displayed. Type 1 looks like this:

and type 2 looks like this:

ShowRecalculateCaptchaButton: This lets you display a button the user can press to show a different number. They may have trouble reading the first one.


Since we have seen what it looks like to use the control, we now need to discuss the steps to install it for use. It is possible to use the control without a DLL, however because the control uses embedded resources (image files), you would need to make modifications to the source for this to work. In this article, I will only discuss using the control as a DLL. Using the DLL approach gives you the most flexibility as well.

Extract the download to an empty directory

First step is to extract the download associated with this article into an empty directory that Visual Studio 2005 can access. Basically, there are two projects in this download. The Class Library project called CaptchaUltimateCustomControl is the project that builds the DLL you will be using in either your C# or VB Web Application Project. The second project is called SampleApp is just simply a sample application built that uses the custom control.

In the sample project, there are three sample pages for demonstration. DefaultNoCustomTemplate.aspx shows building the CAPTCHA control without using a custom template. DefaulDefaultTemplate.aspx shows what happens when you enable a template and make no changes, and DefaultCustomTemplate.aspx shows a more elaborate custom template that can be used for collecting more details information such as name, website, comments, etc. More details will be presented below on these examples. You should be able to run all three sample pages directly now.

Using the Custom CAPTCHA control in your own Project

In order to use the CAPTCHA control in your own project you need to do two things. First, you need to reference the DLL created by the CaptchaUltimateCustomControl project, then you need to add a reference to it as an HttpHandler in your projects web.config.

1. Adding the DLL reference

First, open the project you want to add a reference to the DLL from. Next, go to the Solutions Explorer tab, right click and say "Add Existing Project" as is show below.

Choose the csproj file where you downloaded your CaptchaCustomControl as follows.

At this point, you should see the CAPCHA custom control on your ToolBox. If you don’t, I’ve had the same problem and I understand Microsoft knows about it. Sometimes, exiting and reentering VS2005 clears it up, other times it doesn’t and you may have to load your control by hand. Here is a reference to the bug in vs2005 by an team member from Microsoft. If anyone find a solution to this, please let me know. It is a very frustrating problem if you are building custom controls and using the vs2005 designer.

If it worked correctly, you should see a reference to the control on the tool bar as is shown below.

2. Adding a Reference to the HttpHandler in Web.Config

In order for the control to work correctly both in design and runtime mode, you must add the HttpHandler to your web.config file. If you do not do this, you will not see the actual CAPTCHA image appear in your control. The lines are already added to the SampleApp project’s web.config file in the download so you can use that as a reference. Otherwise, just enter the below lines in your web.config file in the <system.web> section.

          <add type=“PeterKellner.Utils.CaptchaTypeHandlerverb=“GETpath=“CaptchaType.ashx/>

I understand that having to add this to the web.config file is a rather unpleasant burden to place on the custom control user. Fritz Onion has proposed a very clever way of getting around this dependency by having the control actually call itself. I actually followed that pattern but then realized (as others including Fritz had pointed out) that if the page were used in a scenario where URL rewriting was happening, very unexpected and incorrect results would happen. Following the principle of "least surprise", I decided against including this as part of the generic solution. If anyone can suggest a solution that does not involve having to register an HttpHandler, I’d be happy to include it.

Custom Template Support

Before talking about custom template support, it’s worth briefly noting what happens when you drag the CAPTCHA custom server control on a page. Basically, two things happen. First a registration line is added to the page telling the aspx page about possible control references to a given tag, and second, the actual control with this special tag is added to the page. Below shows a typical aspx page where this drag and drop has happened.

<%@ Page Language=”C#” AutoEventWireup=”true” CodeFile=”DefaultNoTemplate.aspx.cs”
    Inherits=”_Default” %>
<%@ Register Assembly=”CaptchaUltimateCustomControl” Namespace=”PeterKellner.Utils”
    TagPrefix=”CAPTCHA” %>
<!DOCTYPE html PUBLIC-//W3C//DTD XHTML 1.0 Transitional//EN” “>
<html xmlns=”>
<head id=”Head1runat=”server>
    <title>Default Simple Template</title>
    <form id=”form1runat=”server>
            <CAPTCHA:CaptchaUltimateControl ID=”CaptchaUltimateControl1runat=”server>

If you look at this page shown above in source, in design view, and single click on the smart tag on the controls upper right hand corner, you will get a menu with three choices: Convert to Template; Reset; and Edit Templates. Below is a picture of these three choices.

If you choose "Convert to template", the lines:

<CAPTCHA:CaptchaUltimateControl ID=”CaptchaUltimateControl1runat=”server>


<CAPTCHA:CaptchaUltimateControl ID=”CaptchaUltimateControl1runat=”serverButtonRedisplayCaptchaText=”Generate New Display NumberCaptchaBackgroundColor=”WhiteCaptchaBorder=”1CaptchaLength=”4CaptchaType=”2CommandArg1=”" CommandArg2=”" CommandArg3=”" CommandArg4=”" CommandArg5=”" EncryptedValue=”"
    FontFamilyString=”Courrier NewHeightCaptchaPixels=”50InvalidCaptchaMessage=”***”
    PlainValue=”" ShowPromo=”TrueShowRecalculateCaptchaButton=”TrueShowTitle=”TrueTitle=”Captcha ControlWidthCaptchaPixels=”140>
        <table runat=”serverbgcolor=”Aquaborder=”1>
            <tr runat=”server>
                <td runat=”servercolspan=”2style=”text-align: center;”>
                    <asp:Label ID=”TitleIDrunat=”server>Captcha Control</asp:Label>
            <tr runat=”server>
                <td runat=”server>
                    <asp:TextBox ID=”VerificationIDrunat=”server></asp:TextBox>
                <td runat=”server>
                    <asp:CustomValidator ID=”CustomValidatorIDrunat=”server>***</asp:CustomValidator>
            <tr runat=”server>
                <td runat=”servercolspan=”2style=”text-align: center;”>
                    <asp:Image ID=”CaptchaImageIDrunat=”serverImageUrl=”~/CaptchaType.ashx/>
            <tr runat=”server>
                <td runat=”servercolspan=”2style=”text-align: center;”>
                    <asp:Button ID=”ButtonDisplayNextIDrunat=”serverText=”Generate New Display Number/>

When you look at the control in design view, it will look the same as before. That is because the template is layed out the same as the default configuration the control itself builds with dynamic controls. There are however some differences. First, in design mode, if you change the Captcha Type, the displayed image at design time does not change. If you don’t have a template, changing CaptchaType will instantly change in the designer the type of CAPTCHA image you see. In addition, certain attributes on the <CAPTCHA:CaptchaUltimateControl> tag will no longer take precedence over what is actually in the template. An example of this is InvalidCaptchaString. You need to actually set the value in the template itself.

A discussion of templates would not be complete without mentioning the types of things that can be done with templates. Simply converting the default control to a template does not buy you anything. However, by enhancing the template to include things like Name, Email, Website, etc can add a lot of power to the control that would otherwise be difficult to encapsulate. Below is a sample template enhanced (called DefaultCustomTemplate.aspx in the download).

And, the source view of this control is as follows:

<CAPTCHA:CaptchaUltimateControl ID=”CaptchaUltimateControl1runat=”serverButtonRedisplayCaptchaText=”Generate New Display NumberCaptchaBackgroundColor=”WhiteCaptchaBorder=”1CaptchaLength=”4CaptchaType=”2CommandArg1=”" CommandArg2=”" CommandArg3=”" CommandArg4=”" CommandArg5=”" EncryptedValue=”"
    FontFamilyString=”Courrier NewHeightCaptchaPixels=”50InvalidCaptchaMessage=”Try Again.”
    PlainValue=”" ShowPromo=”True” ShowRecalculateCaptchaButton=”True” ShowTitle=”True”
    Title=”" WidthCaptchaPixels=”140OnVerified=”CaptchaUltimateControl1_VerifiedOnVerifying=”CaptchaUltimateControl1_Verifying>
        <table bgcolor=”Aquaborder=”1>
                <td colspan=”2style=”text-align: left;”>
                        Leave a Reply</h3>
                    <br />
                <td colspan=”2>
                    <asp:TextBox ID=”TextBoxAuthorrunat=”server></asp:TextBox>
                    <literal>  Name (required)</literal>
                    <br />
                    <asp:TextBox ID=”TextBoxEmailrunat=”server></asp:TextBox>
                    <literal>  Email (will not be published) (required)</literal>
                    <br />
                <td colspan=”2>
                    <asp:TextBox ID=”TextBoxWebsiterunat=”server></asp:TextBox>
                    <literal>  Website (Optional)</literal>
                    <br />
                <td colspan=”2>
                    <asp:TextBox ID=”TextBoxCommentTextMode=”multiLineRows=”10Columns=”60runat=”server></asp:TextBox>
                <td colspan=”2style=”text-align: left;”>
                    <asp:TextBox ID=”VerificationIDStyle=”text-align: left;” runat=”server></asp:TextBox>
                    <asp:CustomValidator ID=”CustomValidatorIDrunat=”server>Try Again.</asp:CustomValidator>
                    <asp:Label ID=”TitleIDStyle=”text-align: right;” runat=”server> </asp:Label>
                <td colspan=”2style=”text-align: left;”>
                    <asp:Image ID=”CaptchaImageIDrunat=”serverImageUrl=”~/CaptchaType.ashx/>
                    <asp:Button ID=”ButtonDisplayNextIDrunat=”serverText=”Show me another set of characters/>

Now that you have the control, the obvious thing to wonder is how to easily use it. For that, you really need event processing. That is what is discussed in the next section.

Event Handling

So, why do we need event handling? Well, I can think of two reasons. The first reason is to allow the CAPTCHA processing to be ignored, say in the case where an already authorized user is running the application, and second so that you can do something when a correct CAPTCHA is verified.

Lets take a look at both cases together for brevity. First thing you want to do is select the Custom CAPTCHA server control in the design mode, right click on properties, then switch the property viewer to events. You will see two events that can be programmed. They are as below, Verified, and Verifying.

Just like the login control suppled with ASP.NET 2.0 (no coincidence), Verified is called after a correct CAPTCHA is processed, and Verifying is called just before the verify operation takes place. In the Verifying event (as shown below) you can override the event parameter ForceVerify to be true and say for example you check to see if the current user had admin rights, you could force the verify to succeed regardless of what the user typed into the text field. In the Verified event, you can do all sorts of things including capture information that was typed into template fields, and even redirect the user to a different page if that is what you want. Below is the complete codebehind page to show examples of this.

public partial class  DefaultCustomTemplate : System.Web.UI.Page
    private string captchaConfirmed = string.Empty;
    private void Page_PreRenderComplete(object sender, EventArgs e)
        LabelVerified.Text = this.captchaConfirmed;

    protected void CaptchaUltimateControl1_Verified(object sender, EventArgs e)

        CaptchaUltimateControl captchaUltimateControl = (CaptchaUltimateControl)sender;
        TextBox textBoxAuthor = (TextBox)captchaUltimateControl.FindControl(“TextBoxAuthor”);
        this.captchaConfirmed = “CAPTCHA Confirmed Event Called with Author “ +
            textBoxAuthor.Text + “.”;

    protected void CaptchaUltimateControl1_Verifying(object sender, VerifyingEventArgs e)
        e.ForceVerify = true;
        this.captchaConfirmed = string.Empty;

Summary and Conclusions

In this first part of a series of articles (not written at the time of this first publication), we showed how to use the UltimateCaptchaControl. Currently, on the internet, you can find many CAPTCHA controls written for ASP.NET 2.0. None I could find have so much richness to be useful without a lot of modifications. I’ve attempted to make this control something you can actually use right away with no changes. The source is of course provided for both study and modifications so you can make changes if you see fit.

The plan for the rest of the series to break down the control into its intrinsic parts and explain those parts piece by piece. Building the control uncovered a lot of areas that are very interesting in the ASP.NET 2.0 environment. Feel free to contact me if you have suggestions for the control or feel you would like something better explained about how it works. I look forward to writing the next several articles on this.


Many many sources of information have been combined to create the Ultimate CAPTCHA server control. I’d like to briefly mention some of the sources that ideas and code were borrowed from (in no particular order).

Jason Diamond – Jason actually wrote the skeleton code of the designer portion of the control. Converting to and from a template is far from obvious and I could not glean how to do this on my own. Jason was huge help in contributing this.

Scott Mitchell – After many hours of wondering why templates were not working, it occured to me (after using reflector) that the controls in template were hierarchical and not linear. To parse all the controls, I used a short (but clever and recursive class) that Scott Mitchell published. In addition, Scott’s prolific writing has been helpful in many ways.

Shanku Niyogi – Author of the Blog Starter Kit at Microsoft, Shanku published some very nice code for generating a CAPTCHA image including generating random bubbles on the image. Very nice touch! His code is what creates the Type2 CAPTCHA images

Mike Hall – Mike Hall, AKA BrainJar published work in 2004 on generating CAPTCHA images in It was his work that the CAPTCHA type one presented here is derived from

Jeff Atwood – Jeff took Mike Hall’s work and extended to be a custom server control. It is from that work that I built the framework of a server control displaying a CAPTCHA image. A very clean implementation. (that hopefully I didn’t over complicate too much)

About Peter Kellner

Follow me:


  1. Hey Man Really a nice CAPTCHA procedure. I am going to implement this in my own website as I am facing too much spamming issues. And will get back to you if I face any issues implementing this CAPTCHA control. Hope you will guide to implement this. 🙂

  2. I really like your captcha! Just wanted to tell you!

  3. Control works great in ASPx page but when I put it in a user web control, the image does not appear until you refresh the image. I have even tried to force a refresh on page load event, but cannot get this to work correctly in user control. I built an ASPX web page for email form and it worked perfectly. Converted to a web control and it appears this captha control is not compatible with user controls.

  4. Leanora Shelley says:

    Hi there, just became aware of your blog by way of Google, and found that it’s really informative. I’m going to watch out for brussels. I’ll appreciate in case you continue this in future. Many folks will be benefited from your writing. Cheers!

  5. Alphonse Bowles says:

    I am always browsing online for ideas that can benefit me. Thanks!

  6. propane outdoor fire pits says:

    This was a very detailed explanation. Thanks

  7. I learned about this webpage via Bing a month ago and I like to have the benefit of reading a post that should make many people think! Thanks so much.

  8. I always wondered how to get captcha working with HTML. Great post propane outdoor fire pits ultimate cheap paintballing

  9. This control could be good Sexy Nail Art designs but i am not sure if it is neccessary. Easy Nail Art designs

  10. A lot of bloggers and web developers have huge problems with spam robots posting spam all over the internet. CAPTCHA (Completely Automated Public Turing test to tell Computers and Humans Apart) is a really great way for that. I’m pretty thankful that something like this exists.

  11. Inchirieri says:

    Wow, this was very hard for me.. but I manage to do it. Now I will implement this captcha to all of my sites

  12. Not only did the control not appear in my tool box, but now i have no tools in my toolbox…

    only a message saying there are no usable controls in your toolbox…

    user beware

  13. robey85 says:

    Before talking about custom template support, it

  14. ansty59 says:

    Before talking about custom template support, it

  15. charlewood36 says:

    Before talking about custom template support, it

  16. Long Black Cardigan says:

    ” CAPTCHA stands for (Completely Automated Public Turing test to tell Computers and Humans Apart).The process typically involves showing the user a distorted picture of text and numbers, then the user must interpret this, type what they see into a text field and the computer checks for correctness.”

    Come to think of it, did those developers thought that there are people who’s got poor eyesight like me have the difficulties reading the CAPTCHA? To tell you honestly, I’m very annoyed everytime I have to enter the unreadable by human eyes CAPTCHA. Please consider us people.

  17. have always known the use of captcha but never known the definitions of it and how it separates humans from computers.

  18. Hi there, just doing some browsing for my San Jose 4g site. Truly more information that you can imagine on the web. Wasn’t what I was looking for, but great site. Have a great day.

  19. I just cofused about one thing. If capcha works so well and prevents from autimatic posting and spamming, why don’t you have it in your blog? and why there is need of post-moderation?

  20. Before talking about custom template support, it

  21. Before talking about custom template support, it

  22. As a reminder, when the page loads (not logged in), everything comes up (the recalculate button, the promo link) but the captcha image. When I load the View Code page, I see that the imageUrl has changed and have something like “CaptchaType.ashx?id=” and a long number id.

  23. I wanted to thank you for this great read!! I definitely enjoying every little bit of it.I have you bookmarked to check out new stuff you post.Thank you for sharing the nice post with useful information.

  24. Awsome post and right to the point. I am not sure if this is really the best place to ask but do you people have any thoughts on where to employ some professional writers? Thank you

  25. Funny how captcha has changed since the article came out – this is pre re-captcha. Good article though.

    Side note- funny that this site does not use captcha.

  26. Sudie Englett says:

    The trouble using Plr article content is buyers usually do not make use of it effectively. They should either put it to use for getting tips for subjects to write about or even totally re-write it or ” spin ” it up and afterward set his or her own identify into it.

  27. Hello, I was looking for offers on Mutoh print heads. Your info came up on Google. I eventually got what I was looking for here: DX4 printheads

  28. Hey hi,
    Artical is awesome. I am looking for Captcha bypass code. If you have any related artical plz post it.

  29. Amazing article, really enjoyed reading and would love to get more updates on further developments in the area

  30. Excellent stuff on The Ultimate CAPTCHA Custom Server Control | I even agree with most of it!

  31. Finally! An extensive and clear article about captcha. I was having trouble with my blog’s captcha source code, it looked simple at first but then I made a mess. This is the best blog I’ve found, it solved all my doubts and more.

  32. Thanks for a great resource page, does anyone know if there is something like this but for WP? thanks

  33. How did you get your captcha to have a gray scale look intead of the rainbow look by default. What are your settings on the control? Thank.

  34. Hey there!!
    How can i customize the CaptchaType to reflect a different background!!

  35. This article was of tremendous help.
    I searched the entire web but found this one honest example with less talk and more code.

    Pushing my luck a little further.

    When the Login Control –> Convert to Template is done the Web Controls has the data bindings like ‘<%# DataBinder.Eval(…" and so on in the HTML.
    Same thing when a Datagrid BoundColumn is converted to a TemplateColumn. The databinding text remains.


    I will check this website for a couple of days for a reply. An email notification when replied would be highly appreciated.

  36. Rosco, Thanks, I fixed the link at the top. -Peter

  37. I’m unable to download from it says Sorry, the file you requested can not be found.

  38. I’m having a hard time adding this control to Visual Web Developer Express 2005. Any ideas on how to do it? I don’t seem to have a “Solution” node on my VWD Express solution explorer window.

  39. Hello Peter, its me again.

    I have verified the httpHandlers web config lines and they are identical as you have in your article. I am using Jeremy Wadsworth’s code and I have not changed anything but some parameters values to test what they do. Then I changed them back to their original state. I am very new at all this (asp, VB, etc..) I do not know where to look. I am using Jeremy’s code under aspnet 3.5 in Godaddy. I am not sure if I have (or need) write privileges in the host. I understand the image is saved in cache. Do I need to set something to allow this?
    As a reminder, when the page loads (not logged in), everything comes up (the recalculate button, the promo link) but the captcha image. When I load the View Code page, I see that the imageUrl has changed and have something like “CaptchaType.ashx?id=” and a long number id.
    Hope you can help/

  40. Hi,
    sorry for the previous posts. I was trying to copy paste the web config lines I used.


  41. Sorry,

  42. Hi,
    Thanks for prompt reply.
    In my web config I have:

    ‘ ‘

  43. Hi,
    Thanks for prompt reply.
    In my web config I have:

    In my asp page I have the following:


    Código de Seguridad.

    Intente de nuevo.

    Do you see something I am doing wrong?

  44. Peter Kellner says:

    Hi Ramon,

    You might want to verify that the image handler is installed correctly in the web.config file.

  45. Hi,
    I have not been able to show the Captcha image. However, the promo link comes up what makes me think is doing something. I am using Godaddy, I don’t know if that might be the issue. Where should I look first?

  46. Thomas Skyum says:

    Actually, ignore the above. I am using AJAX and it appears the 2 don’t play well together.

  47. Thomas Skyum says:

    Hello there, and thanks for supplying the great control.

    Just wanted to report what seems to be a bug:

    When nothing is entered in the TextBox that holds the CAPTCHA characters an exception is thrown in CaptImageUtils.cs:132

    the variable cp has the value null.

    As long as the textbox isn’t empty when a postback occurs it works fine, so I just worked around it by letting the user know via javascript to enter something in the field.

  48. Hello Peter, i am using your Capchta Control for a few days. Its great. But it seems the control does not differ between upper and lower case. Is there a way to configure it? Greetings from Germany, Roland See

  49. Hi Peter,

    What is the best way to clear the textbox for a Reset() method in my own code-behind?

  50. HI
    I try to install the control and i ran into problems.
    i am using visual web devaloper and not visual studio .
    when i first try to run the customControl project i get to visual studio conversion wizard and when it finishes i get an error in converting.
    i am quite new to the .net infrastructure so help will be appreciated?

  51. Bruce, I’ve been trying to get it working in the createuserwizard control. If I get it working I’ll post a reply here. Please do the same if you figure it out.

  52. when I click the “generate new display number” button, sometimes it cannot generate a security code image. I have to click the button many times to generate a new code successfully. can you tell me what cause it?

  53. I just have a quick question about CAPTCHA. I have everything working like it should but when the form page loads for the first time, I have to refresh the page for the CAPTCHA to appear. After that, the image loads fine until the form page is revisited again for a first time. Any help would be greatly appreciated.



  54. Where did you get the CAPTCHA php code for the image in this form? It has a better look than the sample in your download.


  55. Great control. I was able to implement without much trouble. I do have a question. How do I get the control to refresh the image automatically when an invalid code is entered? Thanks

  56. Administrator says:

    It’s important that you make the Cache not removable by changing line 573 of CaptchaUltimateControl.cs to:

    HttpContext.Current.Cache.Insert(cacheKey, cp,null,cacheExpiration, Cache.NoSlidingExpiration,CacheItemPriority.NotRemovable,null);


Get every new post delivered to your Inbox

Join other followers: