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

The ASP.NET Captcha customization sample project shows how to customize BotDetect CAPTCHA behavior and appearance.

First Time Here?

Check the BotDetect Developer Crash Course for key integration steps.

BotDetect 3.0 allows user-defined customization of many Captcha options through a custom <botDetect> configuration section in the web.config file; some customizations also require code-behind changes.

Shown customizations include: CAPTCHA image color scheme, sound & reload icons and their tooltips, custom client-side handlers for BotDetect actions such as sound playing and Captcha reloading (resulting in simple debug messages on icon clicks in this sample), ...

The web.config file used in this sample project contains detailed descriptions and explanations of the many customizable options.

You can then use chosen customization options to configure BotDetect to precisely match your application requirements.

Visual Studio 2013 / Visual Studio 2012 / .NET 4.5

By default, the .NET 4.5 C# version of the ASP.NET Captcha customization sample project is installed at:
C:\Program Files\Lanapsoft\BotDetect 3 CAPTCHA Component\Asp.Net\v4.5\WebApp\CaptchaCustomizationSample\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 CAPTCHA Customization ASP.NET Sample</title>
  <link type="text/css" rel="Stylesheet" href="StyleSheet.css" />
</head>
<body>
  <form id="form1" runat="server">
  <h1>BotDetect CAPTCHA Customization ASP.NET 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>
  
  <h4>Custom BotDetect Client-Side Events Debug Log</h4>
  <div id="output"></div>
  
  <script type="text/javascript">
      function log(text) {
        var output = document.getElementById('output');
        var line = document.createElement('pre');
        line.innerHTML = timestamp() + ' ' + text;
        output.insertBefore(line, output.firstChild);
      }
      
      function timestamp() {
        return new Date().toTimeString().replace(/.*(\d{2}:\d{2}:\d{2}).*/, "$1");
      }
      
      function format(url) {
        return url.replace(/^.*?\?/g, '').replace(/&/g, '\n  &');
      }

      // custom javascript handler executed before Captcha sounds are played
      BotDetect.RegisterCustomHandler('PrePlaySound', function() { 
        log('PrePlaySound: ' + this.Id); 
      });  
      
      // custom javascript handler executed before Captcha images are reloaded
      BotDetect.RegisterCustomHandler('PreReloadImage', function() { 
        log('PreReloadImage:\n  ' + format(this.Image.src) + '\n  AutoReload: ' + 
          this.AutoReloading);
      });  
      
      // custom javascript handler executed after Captcha images are reloaded
      BotDetect.RegisterCustomHandler('PostReloadImage', function() { 
        log('PostReloadImage:\n  ' + format(this.Image.src));
      }); 
    </script> 
    
  </form>
</body>
</html>

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";
            CaptchaCorrectLabel.Text = "Correct!";
            CaptchaIncorrectLabel.Text = "Incorrect!";

            // these messages are shown only after validation
            CaptchaCorrectLabel.Visible = false;
            CaptchaIncorrectLabel.Visible = false;

            // choose the custom charset used for CAPTCHA code generation
            // (various custom charsets can be defined in the web.config file)
            SampleCaptcha.CustomCharacterSetName = "CustomCharset1";

            // customize the CAPTCHA image color scheme
            SampleCaptcha.CustomDarkColor = System.Drawing.Color.DarkSlateBlue;
            SampleCaptcha.CustomLightColor = System.Drawing.Color.LightSkyBlue;
        }

        // setup client-side input processing
        SampleCaptcha.UserInputClientID = CaptchaCodeTextBox.ClientID;

        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.Visible = true;
                CaptchaIncorrectLabel.Visible = false;
            }
            else
            {
                CaptchaCorrectLabel.Visible = false;
                CaptchaIncorrectLabel.Visible = true;
            }
        }
    }
}

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>
    <!-- Register the BotDetect configuration section -->
    <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>
  <!-- BotDetect Captcha settings can be configured in this section -->
  <botDetect>
    <!-- Captcha code settings -->
    <!-- Captcha code timeout in seconds - the Captcha can only be successfully
       solved within the specified time after generation. This is an optional
       security improvement that narrows the window of opportunity for attacks
       based on re-using the Captcha image on another site controlled by the
       attacker, or similar human-solver-based attacks on Captcha-protected
       forms. -->
    <captchaCodes timeout="120">
      <!-- Defines custom character sets for Captcha code generation. You can 
         then map the custom character sets defined here to appropriate Captcha 
         control instances by name in code-behind or .aspx designer. -->
      <characterSets>
        <!-- Full charset specification, defining all 3 code styles. -->
        <characterSet name="CustomCharset1" alpha="A,B,C,D,E" 
          numeric="1,2,3,4" alphanumeric="A,B,C,D,1,2,3"/>
        <!-- If you don't want to distinguish between code styles, you can 
           specify the alphanumeric characters only and they will be used for all 
           Captcha codes regardless of the codeStyle value set. -->
        <characterSet name="CustomCharset2" alphanumeric="A,B,C,D"/>
      </characterSets>
      <!-- Test mode, set to "true" during automated testing of your page to 
         make the Captcha trivially solvable (always use the "TEST" code). Be 
         careful not to enable this on production websites since it will allow
         trivial Captcha bypassing for bots but human users will still -->
         have to solve it. -->
      <testMode enabled="false"/>
    </captchaCodes>
    <!-- Captcha image settings -->
    <captchaImage>
      <!-- Custom Captcha image alt text / title -->
      <captchaImageTooltip>
        <localizedString value="CAPTCHA Image Custom Universal Tooltip" />
        <localizedString locale="es" 
          value="CAPTCHA Image  Custom Spanish Tooltip"/>
      </captchaImageTooltip>
      <!-- The Captcha image is also a link to a locale-dependent help page; 
         with customizable properties:
            - enabled: (true|false) turns the help link on or off
            - mode: (image|text) controls how the link is displayed -->
      <helpLink enabled="true" mode="text">
        <!-- absolute or application-relative help page Urls -->
        <helpPage>
          <localizedString value="~/captcha.html" />
          <localizedString locale="es" 
            value="http://es.captcha.com/captcha.html" />
        </helpPage>
        <!-- text used in the help link -->
        <helpText>
          <localizedString value="Custom CAPTCHA Help Link Text" />
          <localizedString locale="es" 
            value="Custom Spanish CAPTCHA Help Link Text" />
        </helpText>
      </helpLink>
    </captchaImage>
    <!-- Captcha sound settings
      - enabled: Is Captcha sound enabled.
      - startDelay: Starting delay of sound JavaScript playback, in milliseconds. 
        Useful for improving usability of the Captcha sound for blind people using
        JAWS or similar readers, which will read the label associated with the 
        Captcha code textbox and start sound playback simultaneously when the 
        sound icon is activated. Setting this delay to e.g. 2000 (2 seconds) will
        give the user time to hear both the pronounced label and the Captcha sound
        clearly. 
      - regenerationMode: How will multiple consecutive requests for audio 
        Captcha with the same Captcha code ("sound regeneration") be handled  
        by BotDetect - a trade-off of security, usability, and storage requirements:
          -> "none" - generate only one sound response per Captcha code, cache 
            it on the server, and serve it for all consecutive sound requests.
              * High security: comparative analysis of multiple sounds is 
                impossible since only one sound response exists per Captcha code.
              * High usability: works consistently across all browsers, regardless of 
                their Html5 audio support and without depending on JavaScript 
                functionality.
              * High storage requirements: the generated sound bytes must be  
                stored in Session state, consuming server memory or other storage  
                medium for each Captcha code requested as Captcha audio.
          -> "limited" - allow generation of a limited number of different sound 
            responses (the minimum required to make Captcha audio work in all 
            supported client browsers and devices), and automatically change the 
            Captcha code on the client for consecutive sound requests if needed 
            and possible. 
              * Good security: comparative analysis of multiple sounds is severely 
                hampered, since the small number of sound responses available 
                does not provide enough information to seriously undermine Captcha 
                security. 
              * Good usability: Since Captcha sound will only be served a small 
                number of times for the same Captcha code (returning an error after
                the limit has been hit), observed behavior depends on client browser 
                capabilities: 
                  - Modern Html5 Wav audio compatible browsers will always replay 
                    the same sound on consecutive sound icon clicks, without 
                    requesting a regenerated sound from the server.
                  - Older browsers without support for client-side audio replay must
                    detect consecutive sound icon clicks that might trigger the sound 
                    regeneration limit on the server and automatically change the 
                    Captcha code (by reloading the Captcha image) to ensure sound 
                    will play properly. For each sound icon click after the first one, 
                    the
                    Captcha image will be changed before audio is played.
                  - Browsers without JavaScript capability (and bots) will have to 
                    reload the form to get a new Captcha code to make the sound  
                    work again after the regeneration limit had been hit.
              * Low storage requirements: generated sound responses don't need to
                  be stored on the server. 
          -> "unlimited" - each audio request will generate a new Captcha sound 
            response (previous BotDetect version behavior).
              * Low security: comparative analysis of multiple sounds for the same
                Captcha code allows for higher accuracy of automated recognition.
              * High usability: works consistently across all browsers, regardless of 
                their Html5 audio support and without depending on JavaScript 
                functionality. 
              * Low storage requirements: generated sound responses don't need to 
                be  stored on the server.
        BotDetect defaults to limited sound regeneration as the most reasonable 
        overall trade-off. At user discretion, higher security and usability can be 
        achieved at the cost of significant amounts of server-side storage space. 
        Unlimited sound regeneration is not recommended due to low security, 
        but is left as an option for backwards-compatibility. -->
    <captchaSound enabled="true" startDelay="1000" regenerationMode="limited">
      <!-- Captcha sounds in BotDetect 3.0 require locale-dependent 
         pronunciation SoundPackage (.bdsp) files. Some default SoundPackages
         are included in all BotDetect installations, and pronunciations for
         additional languages can be downloaded from the Downloads section
         of the BotDetect website. There are several optional SoundPackage 
         settings:
           - folderPath: Custom sound packages folder. You can reuse a single
               location for all ASP.NET applications using BotDetect
               Captcha on the same server, and don't have to copy the
               SoundPackage files to each and every application's Bin
               folder.
           - warnAboutMissingSoundPackages: If the required SoundPackage in not
               deployed, the sound icon is not clickable and displays
               a warning tooltip by default. If you want to disable
               this warning and simply not display the sound Captcha
               icon at all for locales whose pronunciations are not
               deployed with the application, set this property to "false". -->
      <soundPackages folderPath="C:\Program Files (x86)\Lanapsoft\BotDetect 3 
        CAPTCHA Component\Asp.Net\BotDetectSounds" 
      warnAboutMissingSoundPackages="false"/>
      <!-- Custom sound Captcha icon image & titles -->
      <soundIcon filePath="~/CustomSoundIcon.gif" iconWidth="22">
        <soundIconTooltip>
          <localizedString value="Sound Icon Custom Universal Tooltip"/>
          <localizedString locale="es" 
            value="Sound Icon Custom Spanish Tooltip"/>
        </soundIconTooltip>
      </soundIcon>
    </captchaSound>
    <!-- Captcha reloading settings -->
    <captchaReloading enabled="true">
      <!-- Custom reload Captcha icon image & titles -->
      <reloadIcon filePath="https://captcha.com/images/refresh.png" 
      iconWidth="17">
        <reloadIconTooltip>
          <localizedString value="Reload Icon Custom Universal Tooltip"/>
          <localizedString locale="es" 
            value="Reload Icon Custom Spanish Tooltip"/>
        </reloadIconTooltip>
      </reloadIcon>
      <!-- Captcha images are automatically reloaded when the Captcha code 
         expires (as set in the <captchaCodes timeout="value"> element, 
         or the ASP.NET Session timeout), but only within  a certain interval
         from their first  generation. This allows you to have a short Captcha
         code timeout (e.g. 2 minutes) to narrow the window of opportunity
         for Captcha reusing on other sites or human-solver-powered bots,
         and actual visitors can still fill out your form at their own pace
         and without rushing (since the  Captcha image will be reloaded
         automatically when it is no longer valid).
         Since we don't want infinite sessions when the user leaves the form 
         open in a background browser tab over the weekend (for example), we
         set a reasonable upper limit on the auto-reload period (e.g. 2 
         hours = 7200 seconds). -->
      <autoReloadExpiredCaptchas enabled="true" timeout="7200"/>
    </captchaReloading>
    <!-- Captcha user input textbox client ID can be registered for each 
       Captcha control instance in code-behind or the .aspx designer,
       with several client-side options then becoming available.
       - autoUppercase: Anything the users type in the input textbox will be 
           uppercased on the fly, since Captcha validation is not and should
           not be case-sensitive. This is a small usability improvement 
           that helps communicate that fact to the users clearly.
       - autoClear: The input texbox will be cleared on all Reload icon clicks 
           and auto-reloads, since any previous input in the textbox will be 
           invalidated by Captcha reloading. This is a small usability
           improvement that helps users avoid having to delete the previous
           input themselves.
       - autoFocus: The input texbox will be assigned focus on all Captcha
           Sound and Captcha Reload icon clicks, allowing the users to more
           easily type in the code as they hear it or as the new image loads.
           This does not apply to auto-reloading of expired Captchas, since
           the user might be filling out another field on the form when the
           auto-reload starts and shouldn't be distracted. -->
    <captchaUserInput autoUppercase="true" autoClear="true" autoFocus="true"/>
    <!-- Custom Captcha HttpHandler path, in case the default
       "BotDetectCaptcha.ashx" doesn't suit your application. You can
       customize both the filename and the extension, but you must ensure
       the IIS mapping for the custom extension is set to be processed by
       the ASP.NET runtime. For example, you can use the ".jpg" extension
       only if you re-map ".jpg" requests to be handled by ASP.NET in your
       application's virtual folder, instead of the default IIS file
       system mapping for ".jpg" files. -->
    <captchaUrls requestPath="CaptchaCustomPath.ashx"/>
    <!-- Custom SessionID encryption password, used to secure the SessionID
       value  that has to be passed in the sound Captcha querystring to avoid
       sound mismatch problems in some older browsers. The SessionID is never
       passed in plaintext querystring to avoid Session hijacking or spoofing
       attacks, and you should specify your own unique encryption password to
       secure it properly. -->
    <captchaEncryption encryptionPassword="SecretEncryptionPassword"/>
    <!-- Custom Captcha Http request validator, allowing only a certain number
       of repeated requests with identical querystrings. Human users in
       normal browsers will always use unique querystrings to access Captcha
       images and sounds (the way the Captcha control works guarantees this),
       while simple bots will often repeat the same request in short time
       intervals. This is a simple measure that increases Captcha security
       by stopping to serve Captcha images and sounds to such obvious bots
       (Captcha is used for bot detection, and in such a case we can detect
       that a bot is involved even without wasting resources on generating
       more Captcha images or sounds). -->
    <captchaRequestFilter enabled="true" allowedRepeatedRequests="3"/>
    <!-- Should Captcha SessionState persistence diagnostics be run on all
       control renders and Http requests. Allows Session troubleshooting,
       detectiong the following conditions:
         - IsSessionHttpModuleRunning (full trust only)
         - IsCustomSessionIdManagerIncluded (full trust only)
         - IsSessionStateEmpty
         - IsNewSession (on PostBack and all HttpHandler requests)
         - IsCaptchaPersistenceEmpty (for initialized CaptchaControls only) -->
    <captchaSessionTroubleshooting enabled="true"/>
    <!-- Should Captcha HttpHandler diagnostics be run on all control
       renders. This is useful while developing your page, but can be turned
       off for production deployments after you ensure the Captcha image
       is showing properly.-->
    <captchaHttpHandlerTroubleshooting enabled="true"/>
    <!-- Should BotDetect also add the remote JavaScript include loaded from the 
       captcha.com server. Currently used only for stats, but planned to develop into 
       additional Captcha functionality -->
    <captchaRemoteScript enabled="true" />
  </botDetect>
  <system.web>
    <httpHandlers>
      <!-- Register the HttpHandler used for BotDetect Captcha requests -->
      <add verb="GET" path="CaptchaCustomPath.ashx" 
        type="BotDetect.Web.CaptchaHandler, BotDetect"/>
    </httpHandlers>
    <!-- Register a custom SessionIDManager for BotDetect Captcha requests, which will 
      prevent sound Captcha mismatch problems in some older browsers and media players -->
    <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 enableSessionState="true" controlRenderingCompatibilityVersion="4.5">
      <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="true" 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"/>
    <trace enabled="false" localOnly="true"/>
    <httpCookies httpOnlyCookies="true"/>
    <trust level="Medium" originUrl=""/>
    <authentication mode="None"/>
    <customErrors mode="RemoteOnly"/>
  </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="CaptchaCustomPath.ashx" type="BotDetect.Web.CaptchaHandler, BotDetect"/>
    </handlers>
  </system.webServer>
</configuration>

Visual Studio 2010 / .NET 4.0

By default, the .NET 4.0 C# version of the ASP.NET Captcha Customization sample project is installed at:
C:\Program Files\Lanapsoft\BotDetect 3 CAPTCHA Component\Asp.Net\v4.0\WebApp\CaptchaCustomizationSample\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 customization sample project is installed at:
C:\Program Files\Lanapsoft\BotDetect 3 CAPTCHA Component\Asp.Net\v3.5\WebApp\CaptchaCustomizationSample\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 customization sample project is installed at:
C:\Program Files\Lanapsoft\BotDetect 3 CAPTCHA Component\Asp.Net\v2.0\WebApp\CaptchaCustomizationSample\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.