ASP.NET CAPTCHA Ajax Validation C# Code Sample (BotDetect v3.0; deprecated)

The ASP.NET CAPTCHA Ajax validation sample project shows how to properly perform Ajax CAPTCHA validation using built-in BotDetect CAPTCHA client-side functionality, which doesn't require any 3rd party Ajax frameworks.

First Time Here?

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

Ajax CAPTCHA validation improves the user experience by reducing CAPTCHA validation response time, giving users much faster feedback about the validation result.

Client-side validation is not secure by itself (it can be bypassed trivially), so the sample also shows how the protected form action must always be secured by server-side CAPTCHA validation as well.

In case of any Ajax errors or timeouts, the sample simply falls back to full form posting and server-side CAPTCHA validation.

Visual Studio 2013 / Visual Studio 2012 / .NET 4.5

By default, the .NET 4.5 C# version of the ASP.NET Captcha Ajax Validation sample project is installed at:
C:\Program Files\Lanapsoft\BotDetect 3 CAPTCHA Component\Asp.Net\v4.5\WebApp\CaptchaAjaxValidationSample\CSharp

You can also run it from the BotDetect Start Menu:
Programs > Lanapsoft > BotDetect 3 CAPTCHA Component > ASP.NET > DotNET 4.5 Web Applications > Run

Default.aspx

<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" 
  Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
  <title>BotDetect ASP.NET CAPTCHA Ajax Validation Sample</title>
  <link type="text/css" rel="Stylesheet" href="StyleSheet.css" />
</head>
<body>
  <form id="form1" runat="server">
  <h1>BotDetect ASP.NET CAPTCHA Ajax Validation Sample</h1>
  <fieldset>
    <legend>CAPTCHA Validation</legend>
    <p class="prompt">
      <label for="CaptchaCodeTextBox">Retype the characters from the picture:</label>
    </p>
    <BotDetect:Captcha ID="SampleCaptcha" runat="server" />
    <div class="validationDiv">
      <asp:TextBox ID="CaptchaCodeTextBox" runat="server"></asp:TextBox>
      <asp:Button ID="ValidateCaptchaButton" runat="server" />
      <asp:Label ID="CaptchaCorrectLabel" runat="server" CssClass="correct">
      </asp:Label>
      <asp:Label ID="CaptchaIncorrectLabel" runat="server" CssClass="incorrect">
      </asp:Label>
    </div>
  </fieldset>
  <script type="text/javascript">
    function OnCaptchaValidate() {
      // update display and disable the button
      document.getElementById('CaptchaCorrectLabel').style.display = 'none';
      document.getElementById('CaptchaIncorrectLabel').style.display = 'none';
      
      document.getElementById('ValidateCaptchaButton').disabled = true;
      document.getElementById('ValidateCaptchaButton').value = 'Validating...';
    }
    
    function OnCaptchaCorrect() {
      // update display
      document.getElementById('CaptchaCorrectLabel').innerHTML = 'Correct! (client)';
      document.getElementById('CaptchaCorrectLabel').style.display = 'inline';
      
      document.getElementById('CaptchaIncorrectLabel').style.display = 'none';
      
      // automatically proceed to server-side validation
      document.getElementById('ValidateCaptchaButton').disabled = false;
      document.getElementById('ValidateCaptchaButton').focus();
      document.getElementById('ValidateCaptchaButton').click();
    }
    
    function OnCaptchaIncorrect() {
      // update display and enable the button for re-tries
      document.getElementById('CaptchaCorrectLabel').style.display = 'none';
      
      document.getElementById('CaptchaIncorrectLabel').innerHTML = 'Incorrect! (client)';
      document.getElementById('CaptchaIncorrectLabel').style.display = 'inline';
      
      document.getElementById('ValidateCaptchaButton').disabled = false;
      document.getElementById('ValidateCaptchaButton').value = 'Validate';
    }
            
    function OnAjaxError() {
      // fall back to server-side validation
      document.getElementById('ValidateCaptchaButton').disabled = false;
      document.getElementById('ValidateCaptchaButton').focus();
      document.getElementById('ValidateCaptchaButton').click();
    }
  </script>
  </form>
</body>
</html>

The Captcha Ajax validation workflow is controlled by the four client-side methods defined on the page: OnCaptchaValidation, OnCaptchaCorrect, OnCaptchaIncorrect and OnAjaxError.

Handlers for the four Ajax-related client-side events will be automatically called by the Validate() function call at appropriate stages of the Ajax Captcha validation workflow.

Main concerns of these handlers are displaying the validation result, disabling multiple consecutive button clicks while Ajax validation is in progress, and handling Ajax errors and timeouts.

Details of the Ajax implementation are encapsulated in BotDetect source for easier use. They involve making an Ajax request at a special endpoint in the Captcha handler, and processing the returned JSON result. You do not need to concern yourself with such details, but can use the supplied Validate() function as is.

Default.aspx.cs

using System;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class _Default : System.Web.UI.Page 
{
    protected void Page_PreRender(object sender, EventArgs e)
    {
        // initial page setup
        if (!IsPostBack)
        {
            // set control text
            ValidateCaptchaButton.Text = "Validate";

            // these messages are shown only after validation
            CaptchaCorrectLabel.Attributes.CssStyle["display"] = "none";
            CaptchaIncorrectLabel.Attributes.CssStyle["display"] = "none";
        }

        // setup client-side input processing
        SampleCaptcha.UserInputClientID = CaptchaCodeTextBox.ClientID;
        ValidateCaptchaButton.OnClientClick = 
          String.Format("return {0}.Validate();", SampleCaptcha.CaptchaId);

        // client-side custom event handlers
        string script = @"
          BotDetect.RegisterCustomHandler('PreAjaxValidate', OnCaptchaValidate);
          BotDetect.RegisterCustomHandler('AjaxValidationFailed', OnCaptchaIncorrect);
          BotDetect.RegisterCustomHandler('AjaxValidationPassed', OnCaptchaCorrect);
          BotDetect.RegisterCustomHandler('AjaxValidationError', OnAjaxError);";
        
        this.Page.ClientScript.RegisterStartupScript(this.GetType(), 
          "BotDetectCustomEventHandlers", script, true);

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

            if (isHuman)
            {
                CaptchaCorrectLabel.Attributes.CssStyle["display"] = "inline";
                CaptchaIncorrectLabel.Attributes.CssStyle["display"] = "none";
                CaptchaCorrectLabel.Text = "Correct (server)!";
            }
            else
            {
                CaptchaCorrectLabel.Attributes.CssStyle["display"] = "none";
                CaptchaIncorrectLabel.Attributes.CssStyle["display"] = "inline";
                CaptchaIncorrectLabel.Text = "Incorrect (server)!";
            }
        }
    }
}

During page setup, we register the four client-side methods defined before as BotDetect Ajax event handlers, and set BotDetect Ajax validation (calling the Validate() function exposed by the BotDetect client-side object interface) as the button ClientClick handler.

During page submission, we perform Captcha validation as usual, since Ajax validation is simply a client-side usability improvement which doesn't affect server-side processing at all. Label text and display style is slightly adjusted from the basic sample, to make tracking the combined client- and server-side Captcha validation workflow easier.

Web.config

<?xml version="1.0"?>
<!--
  For more information on how to configure your ASP.NET application, please visit
  http://go.microsoft.com/fwlink/?LinkId=169433
  -->
<configuration>
  <configSections>
    <section name="botDetect" requirePermission="false" 
      type="BotDetect.Configuration.BotDetectConfigurationSection, BotDetect"/>
  </configSections>
  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>
    <add key="ValidationSettings:UnobtrusiveValidationMode" value="None"/>
  </appSettings>
  <system.web>
    <httpHandlers>
      <!-- Register the HttpHandler used for BotDetect Captcha requests -->
      <add verb="GET" path="BotDetectCaptcha.ashx" 
        type="BotDetect.Web.CaptchaHandler, BotDetect"/>
    </httpHandlers>
    <!-- Register a custom SessionIDManager for BotDetect Captcha requests -->
    <sessionState mode="InProc" cookieless="AutoDetect" timeout="20" 
      sessionIDManagerType="BotDetect.Web.CustomSessionIdManager, BotDetect"/>
    <!-- Session state is required for BotDetect storage; you can also turn if off 
      globally and only enable for BotDetect-protected pages if you prefer -->
    <pages controlRenderingCompatibilityVersion="4.5" enableSessionState="true">
      <controls>
        <!-- Register the BotDetect tag prefix for easier use in all pages -->
        <add assembly="BotDetect" namespace="BotDetect.Web.UI" tagPrefix="BotDetect"/>
      </controls>
    </pages>
    <compilation debug="false" targetFramework="4.5"/>
    <httpRuntime requestValidationMode="4.5" targetFramework="4.5" 
      encoderType="System.Web.Security.AntiXss.AntiXssEncoder, System.Web, 
        Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
    <machineKey compatibilityMode="Framework45"/>
  </system.web>
  <system.webServer>
    <validation validateIntegratedModeConfiguration="false"/>
    <handlers>
      <!-- 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"/>
    </handlers>
  </system.webServer>
  <botDetect>
    <captchaImage>
      <helpLink enabled="true" mode="image" />
    </captchaImage>
  </botDetect>
</configuration>

There are several BotDetect-related changes in the web.config file, including Captcha HttpHandler registration, ASP.NET Session state configuration, and BotDetect tag prefix registration.

Visual Studio 2010 / .NET 4.0

By default, the .NET 4.0 C# version of the ASP.NET Captcha Ajax Validation sample project is installed at:
C:\Program Files\Lanapsoft\BotDetect 3 CAPTCHA Component\Asp.Net\v4.0\WebApp\CaptchaAjaxValidationSample\CSharp

You can also run it from the BotDetect Start Menu:
Programs > Lanapsoft > BotDetect 3 CAPTCHA Component > ASP.NET > DotNET 4.0 Web Applications > Run

The Visual Studio 2010 / .NET 4.0 source has no essential differences from the Visual Studio 2013 / Visual Studio 2012 / .NET 4.5 source.

Visual Studio 2008 / .NET 3.5

By default, the .NET 3.5 C# version of the ASP.NET Captcha Ajax Validation sample project is installed at:
C:\Program Files\Lanapsoft\BotDetect 3 CAPTCHA Component\Asp.Net\v3.5\WebApp\CaptchaAjaxValidationSample\CSharp

You can also run it from the BotDetect Start Menu:
Programs > Lanapsoft > BotDetect 3 CAPTCHA Component > ASP.NET > DotNET 3.5 Web Applications > Run

The Visual Studio 2008 / .NET 3.5 source has no essential differences from the Visual Studio 2013 / Visual Studio 2012 / .NET 4.5 source.

Visual Studio 2005 / .NET 2.0

By default, the .NET 2.0 C# version of the ASP.NET Captcha Ajax Validation sample project is installed at:
C:\Program Files\Lanapsoft\BotDetect 3 CAPTCHA Component\Asp.Net\v2.0\WebApp\CaptchaAjaxValidationSample\CSharp

You can also run it from the BotDetect Start Menu:
Programs > Lanapsoft > BotDetect 3 CAPTCHA Component > ASP.NET > DotNET 2.0 Web Applications > Run

The Visual Studio 2005 / .NET 2.0 source has no essential differences from the Visual Studio 2013 / Visual Studio 2012 / .NET 4.5 source.


Please Note

The information on this page is out of date and applies to a deprecated version of BotDetect™ CAPTCHA (v3.0).

An up-to-date equivalent page for the latest BotDetect Captcha release (v4) is BotDetect v4 Captcha documentation index.

General information about the major improvements in the current BotDetect release can be found at the What's New in BotDetect v4.0 page.