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.