How To Add BotDetect CAPTCHA Protection to ASP.NET WebForms Applications

BotDetect ASP.NET Captcha protection can be added to your ASP.NET WebForms applications using the default <BotDetect:WebFormsCaptcha> custom Web Control. Displaying the Captcha challenge can be as simple as:
<BotDetect:WebFormsCaptcha ID="ExampleCaptcha" 
                           UserInputID="CaptchaCode" runat="server" />
and checking user input when the form is submitted:
bool isHuman = ExampleCaptcha.Validate(userInput);

First Time Here?

Check the BotDetect ASP.NET WebForms Captcha Quickstart for key integration steps.

You can also see how BotDetect Captcha protection has been added to various kinds of ASP.NET forms and projects by running the BotDetect Captcha ASP.NET integration code examples coming with the BotDetect installation.

You can reuse the example projects source code (both C# and VB.NET are available) that fits your application requirements.

CAPTCHA Integration Steps

When adding BotDetect Captcha protection to an ASP.NET WebForms application:

  1. Display a Captcha challenge on the Asp.Net form
  2. Check is the visitor a human on form PostBack
  3. Further Captcha customization and options

I. Display a CAPTCHA Challenge on the ASP.NET Form

Before protecting a form action in your ASP.NET WebForms application with BotDetect Captcha, you should decide how to call the Captcha instance and the related textbox you will use. In this guide, we will use ExampleCaptcha and CaptchaCode. If you plan to protect multiple forms within the same ASP.NET WebForms application, you should take care to give each Captcha instance a different name (e.g. LoginCaptcha, RegisterCaptcha, CommentCaptcha etc.).

To display a Captcha test on a form in an ASP.NET WebForms application, we must reference the BotDetect assembly, add several controls to the form's .aspx source, and register both the tag prefix used by BotDetect controls and the HttpHandler used to display Captcha images.

Reference the BotDetect.dll Assembly

Run the following command in the Package Manager Console:

PM> Install-Package Captcha

After the command execution, the references to the BotDetect.dll, BotDetect.Web.Mvc.dll, and System.Data.SQLite.dll assemblies will be added to your project.

If your project is not going to be using the Simple API, the System.Data.SQLite.dll assembly reference can be safely removed from it.

Add a <BotDetect:WebFormsCaptcha> Control to the Form

On the ASP.NET form you want to protect with BotDetect Captcha, add the following ASP.NET controls:

  • A BotDetect:WebFormsCaptcha control which will display the Captcha challenge
  • An asp:TextBox for the Captcha code user input
  • An asp:Label for the textbox, displaying Captcha instructions
  • An asp:Label which will display Captcha validation errors

The resulting fragment in your .aspx file could look like:

<asp:Label ID="CaptchaLabel" runat="server" AssociatedControlID="CaptchaCode">
  Retype the characters from the picture:
</asp:Label>
<BotDetect:WebFormsCaptcha ID="ExampleCaptcha" 
                           UserInputID="CaptchaCode" runat="server" />
<asp:TextBox ID="CaptchaCode" runat="server" />
<asp:Label ID="CaptchaErrorLabel" runat="server"/>

Register the BotDetect Tag Prefix

For your form to recognize the Captcha control as used above, the BotDetect: control tag prefix must be registered. The simplest way to achieve this is to add the following declaration to the top of your form .aspx source, just below the <%@ Page directive:

<%@ Register Assembly="BotDetect" Namespace="BotDetect.Web.UI"
    TagPrefix="BotDetect" %>

(Option) Global BotDetect Tag Prefix Registration

Alternatively, if you want to use the BotDetect:WebFormsCaptcha control on multiple forms within a single ASP.NET WebForms application, and want to avoid having to paste the above <%@ Register directive on each form individually, you can register the BotDetect tag prefix in your application's Web.config file:

  • Locate the <system.web> -> <pages> -> <controls> section
  • Add the following line to its bottom (just before the closing </controls> tag):
    <!-- Register the BotDetect tag prefix for easier use in all pages -->
    <add assembly="BotDetect" namespace="BotDetect.Web.UI"
        tagPrefix="BotDetect"/>

Register the BotDetect HttpHandler for CAPTCHA Requests

BotDetect uses a special HttpHandler for Captcha requests (Captcha images, sounds, resources...), which needs to be registered in your application before Captcha images will be displayed. This registration is a two-step process:

1. Base HttpHandler Registration

  • Locate the <system.web> -> <httpHandlers> section of the web.config file.
  • Add the following BotDetect handler registration to this section:
    <!-- Register the HttpHandler used for BotDetect Captcha requests -->
    <add verb="GET" path="BotDetectCaptcha.ashx" 
        type="BotDetect.Web.CaptchaHandler, BotDetect"/>

2. IIS 7.0+ HttpHandler Registration

  • Locate the <system.webServer> -> <handlers> section of the web.config file.
  • Add the following BotDetect handler registration to this section:
    <!-- Register the HttpHandler used for BotDetect Captcha requests
      (IIS 7.0+) -->
    <remove name="BotDetectCaptchaHandler"/>
    <add name="BotDetectCaptchaHandler" preCondition="integratedMode"
        verb="GET" path="BotDetectCaptcha.ashx"
        type="BotDetect.Web.CaptchaHandler, BotDetect"/>

Once all of these steps have been performed, the Captcha should be displayed when you open your form in a browser:

BotDetect CAPTCHA added to an ASP.NET form

If the Captcha image isn't being rendered properly, please check the BotDetect integration FAQ.

II. Check is the Visitor a Human on Form PostBack

Once the Captcha challenge is displayed on your form, the code processing form submissions can check if the Captcha was solved successfully and deny access to bots.

This code needs to access the Captcha and textbox control instances added to the form; ASP.NET Session state must also be enabled before Captcha validation can work.

Add CAPTCHA Validation Logic to Page Code-Behind

When the form is submitted, the Captcha validation result must be checked and the protected action (user registration, comment posting, email sending, ...) only performed if the Captcha test was passed. For example:

[C#]

protected void Page_PreRender(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        // initialize the Captcha validation error label
        CaptchaErrorLabel.Text = "Incorrect CAPTCHA code!";
        CaptchaErrorLabel.Visible = false;
    }

    // setup client-side input processing
    ExampleCaptcha.UserInputID = CaptchaCode.ClientID;

    if (IsPostBack)
    {
        // validate the Captcha to check we're not dealing with a bot
        string userInput = CaptchaCode.Text;
        bool isHuman = ExampleCaptcha.Validate(userInput);
        CaptchaCode.Text = null; // clear previous user input

        if (isHuman)
        {
            CaptchaErrorLabel.Visible = false;
            // TODO: proceed with protected action
        }
        else
        {
            CaptchaErrorLabel.Visible = true;
        }
    }
}

[VB.NET]

Protected Sub Page_PreRender(ByVal sender As Object, ByVal e As _
    System.EventArgs) Handles Me.PreRender

    If Not IsPostBack Then
        ' initialize the Captcha validation error label
        CaptchaErrorLabel.Text = "Incorrect!"
        CaptchaErrorLabel.Visible = False
    End If

    ' setup client-side input processing
    ExampleCaptcha.UserInputID = CaptchaCode.ClientID

    If IsPostBack Then
        ' validate the Captcha to check we're not dealing with a bot
        Dim userInput As String, isHuman As Boolean
        userInput = CaptchaCode.Text
        isHuman = ExampleCaptcha.Validate(userInput)
        CaptchaCode.Text = "" ' clear previous user input

        If isHuman Then
            CaptchaErrorLabel.Visible = False
            ' TODO: proceed with protected action
        Else
            CaptchaErrorLabel.Visible = True
        End If
    End If
End Sub

Getting the CAPTCHA Validation Result

The user input for the Captcha code can be read from the textbox you added to the form (called CaptchaCode in this guide so far), and the boolean result of Captcha validation can be determined by calling the Validate() method on the Captcha control instance.

Since it only makes sense to make this check when the form is submitted, this code should be placed within a Page.IsPostBack check. We should also take care not the validate the same user input more than once, since every Captcha code can only be validated once for security reasons.

For the same reason, there is no point to remembering previous user Captcha code input, so we always clear the textbox value after Captcha validation (regardless of the validation result).

This (and much more) is explained in the BotDetect Captcha validation and security FAQ.

CAPTCHA Validation Failure

If Captcha validation failed, you should display an error message to the user and instruct them to try retyping it again. You should also cancel the protected action that you want only human visitors to have access to.

CAPTCHA Validation Success

If Captcha validation succeeded, the visitor has proven to be a human and not a bot, and you can proceed with the protected action.

(Option) Getting the CAPTCHA Control References Placed in a <ContentLayout>

If you placed the Captcha on the form within a <ContentLayout> of another ASP.NET control (such as the <asp:Login> and <asp:CreateUserWizard> controls), you will not be able to access the textbox and Captcha control instances directly by name as shown above.

In this case, you can use FindControl() calls on the container to get control instances by name. For example, in case of an ASP.NET login form Captcha placed within a <asp:Login> control called ExampleLogin, you would use:

[C#]

TextBox CaptchaCode = ExampleLogin.FindControl("CaptchaCode") as TextBox;
Captcha ExampleCaptcha = ExampleLogin.FindControl("ExampleCaptcha") as Captcha;

[VB.NET]

Dim CaptchaCode As TextBox = _
    TryCast(ExampleLogin.FindControl("CaptchaCode"), TextBox)

Dim ExampleCaptcha As Captcha = _
    TryCast(ExampleLogin.FindControl("ExampleCaptcha"), Captcha)

Or, in case of an ASP.NET registration form Captcha placed within a <asp:CreateUserWizard> control called RegisterUser:

[C#]

TextBox CaptchaCode = RegisterUser.CreateUserStep.
    ContentTemplateContainer.FindControl("CaptchaCode") as TextBox;

Captcha ExampleCaptcha = RegisterUser.CreateUserStep.
    ContentTemplateContainer.FindControl("ExampleCaptcha") as Captcha;

[VB.NET]

Dim CaptchaCode As TextBox = TryCast( _
    RegisterUser.CreateUserStep.ContentTemplateContainer.FindControl( _
        "CaptchaCode"), TextBox)

Dim ExampleCaptcha As Captcha = TryCast( _
    RegisterUser.CreateUserStep.ContentTemplateContainer.FindControl( _
        "ExampleCaptcha"), Captcha)

In all cases, you can then get the Captcha validation result using those control instances as shown above. You can see an example of this code in the ASP.NET WebForms Captcha register form example code.

Configure ASP.NET Session State

BotDetect Captcha validation requires ASP.NET Session state – generated random Captcha codes have to be stored on the server and compared to the user input. Also, to ensure Captcha sounds work properly in all browsers, a custom SessionIDManager (implementing an optional but recommended improvement) should be registered.

  • In the <system.web> section of the web.config file, locate the <pages> element and set the enableSessionState attribute:
    <pages enableSessionState="true">
  • In the <system.web> section of the web.config file, locate the <sessionState> element if it exists, or add it if it doesn't.
  • Add the following attribute to the declaration:
    sessionIDManagerType="BotDetect.Web.CustomSessionIdManager, BotDetect"
The most common resulting declaration would be:
<sessionState mode="InProc" cookieless="AutoDetect" timeout="20"
    sessionIDManagerType="BotDetect.Web.CustomSessionIdManager, BotDetect"/>

You can use a different Session State mode or options, since BotDetect works with all of them. For more information about BotDetect and ASP.NET Session state, and debugging tips in case the Captcha validation is failing even when you type the correct Captcha code, please check the BotDetect persistence options FAQ.

(Option) Including the CAPTCHA Validation Result in Page.IsValid

The above Captcha validation code is based on getting the Captcha validation result directly as a boolean. It is also possible to integrate it with ASP.NET WebForms validation of other form fields using a <asp:CustomValidator> control.

This would allow you to use the Captcha validation result in a validation summary, and have your code only check the overall validity of the whole form (instead of checking the Captcha separately from other form fields).

For example, you could attach the following control to the Captcha code textbox:

<asp:CustomValidator runat="server" ID="CaptchaValidator"
  ControlToValidate="CaptchaCode"
  ErrorMessage="Incorrect CAPTCHA code!"
  OnServerValidate="CaptchaValidator_ServerValidate" />

and then place the Captcha validation code within the CaptchaValidator_ServerValidate event handler in form code-behind:

[C#]

protected void CaptchaValidator_ServerValidate(object source,
    ServerValidateEventArgs args)
{
    // validate the Captcha to check we're not dealing with a bot
    args.IsValid = ExampleCaptcha.Validate(args.Value);

    CaptchaCode.Text = null; // clear previous user input
}

[VB.NET]

Protected Sub CaptchaValidator_ServerValidate(ByVal source As Object,
    ByVal args As ServerValidateEventArgs)

    ' validate the Captcha to check we're not dealing with a bot
    args.IsValid = RegisterCaptcha.Validate(args.Value)

    CaptchaCode.Text = Nothing ' clear previous user input
End Sub

The registration form Captcha shown in the ASP.NET WebForms application template Captcha example uses both a <asp:RequiredFieldValidator> and a <asp:CustomValidator> to ensure only human visitors can register new user accounts.

A variant of this code is also implemented by the <BotDetect:CaptchaValidator> control and shown in the ASP.NET Captcha Validator example.

III. Further CAPTCHA Customization and Options

BotDetect ASP.NET Captcha allows detailed customization of many Captcha properties, and you can read more about them in the BotDetect Captcha configuration How To.