ASP.NET CAPTCHA Code Filtering C# Code Sample

The ASP.NET Captcha code filtering sample project shows how to use the new CAPTCHA code filtering functionality added in BotDetect CAPTCHA v3.0.

You can define rules about character sequences you want to avoid using in randomly generated CAPTCHA codes and simply pass them to the Captcha control.

First Time Here?

Check the BotDetect Developer Crash Course for key integration steps.

The web.config file defines a simplified custom character set (using only 'A', 'B', 'C' and 'D'), which helps make the code filtering easier to track in action. The following sequences will never appear in Captcha codes generated in the sample: D, AA, BB, CC, ABC, BCA, CAB.

The Global.asax file shows three different ways to load the banned sequence definitions: from a plain-text file, a .csv file, and a web.config setting.

For your application you will typically use only one of these three approaches, or any other method you prefer - you can keep the definitions in any format or combination of formats, and you just have to pass a List<string> value to the Captcha control class.

Download the BotDetect ASP.NET CAPTCHA Component and run this sample

Visual Studio 2012 / .NET 4.5

By default, the .NET 4.5 C# version of the ASP.NET Captcha code filtering sample project is installed at:
C:\Program Files\Lanapsoft\BotDetect 3 CAPTCHA Component\Asp.Net\v4.5\WebApp\CaptchaCodeFilteringSample\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

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

Visual Studio 2010 / .NET 4.0

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

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 Code Filtering ASP.NET Sample</title>
  <link type="text/css" rel="Stylesheet" href="StyleSheet.css" />
</head>
<body>
  <form id="form1" runat="server">
  <h1>BotDetect CAPTCHA Code Filtering 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>
  </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;
        }

        // 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;
            }
        }
    }
}

Global.asax

<%@ Application Language="C#" %>

<script runat="server">

    void Application_Start(object sender, EventArgs e) 
    {
        // Code that runs on application startup
        System.Collections.Generic.List<string> bannedSequences = new 
        System.Collections.Generic.List<string>();

        // add entries from a line-separated text file
        using (System.IO.StreamReader input = System.IO.File.OpenText(
        Server.MapPath("BannedSequences.txt")))
        {
            string line;
            while (BotDetect.StringHelper.HasValue(line = input.
            ReadLine()))
            {
                bannedSequences.Add(line.Trim());
            }
        }

        // add entries from a comma-separated text file
        using (System.IO.StreamReader input = System.IO.File.OpenText(
        Server.MapPath("BannedSequences.csv")))
        {
            string csvString = input.ReadToEnd();
            string[] banned = BotDetect.StringHelper.CsvToArray(
            csvString);
            bannedSequences.AddRange(banned);
        }
        
        // add entries from web.config
        string csvConfiguredString = ConfigurationManager.AppSettings[
        "LBD_BannedSequences"];
        if (BotDetect.StringHelper.HasValue(csvConfiguredString))
        {
            string[] configured = BotDetect.StringHelper.CsvToArray(
            csvConfiguredString);
            bannedSequences.AddRange(configured);
        }

        // this list is static and applies to all Captcha instances in 
        the application
        BotDetect.Web.UI.Captcha.BannedSequences = bannedSequences;
    }
    
    void Application_End(object sender, EventArgs e) 
    {
        //  Code that runs on application shutdown

    }
        
    void Application_Error(object sender, EventArgs e) 
    { 
        // Code that runs when an unhandled error occurs

    }

    void Session_Start(object sender, EventArgs e) 
    {
        // Code that runs when a new session is started

    }

    void Session_End(object sender, EventArgs e) 
    {
        // Code that runs when a session ends. 
        // Note: The Session_End event is raised only when the 
        sessionstate mode
        // is set to InProc in the Web.config file. If session mode is 
        set to StateServer 
        // or SQLServer, the event is not raised.

    }
       
</script>

BannedSequences.csv

d,aa,bb,cc,abc,bca,cab

BannedSequences.txt

d
aa
bb
cc
abc
bca
cab

Web.config

<?xml version="1.0"?>
<configuration xmlns="http://schemas.microsoft.com/.
NetConfiguration/v2.0">
  <configSections>
    <!-- Register the BotDetect configuration section -->
    <section name="botDetect" requirePermission="false" 
    type="BotDetect.Configuration.BotDetectConfigurationSection, 
    BotDetect"/>
  </configSections>
  <!-- BotDetect Captcha settings can be configured in this section -->
  <botDetect>
    <captchaCodes>
      <!-- Define custom character sets to use for Captcha code 
      generation -->
      <characterSets>
        <characterSet name="CodeFilteringExampleCharset" 
        alphanumeric="A,B,C,D"/>
      </characterSets>
    </captchaCodes>
  </botDetect>
  <appSettings>
    <add key="LBD_BannedSequences" value="d,aa,bb,cc,abc,bca,cab"/>
  </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 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="true" targetFramework="4.0">
      <assemblies>
        <add assembly="System.Design, Version=4.0.0.0, Culture=neutral,
        PublicKeyToken=B03F5F7F11D50A3A"/>
      </assemblies>
    </compilation>
    <trace enabled="false" localOnly="true"/>
    <httpCookies httpOnlyCookies="true"/>
    <trust level="Medium" originUrl=""/>
    <authentication mode="None"/>
    <customErrors mode="RemoteOnly"></customErrors>
  </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>
</configuration>

The Captcha code filtering algorithm works as shown in the example.

  • If the first character is "a", for second character generation we check:
    • all banned sequences of length = 2 starting with "a"
    giving us a set of characters to exclude for second character generation.
  • If the first two characters are "ab", for third character generation we check:
    • all banned sequences of length = 3 starting with "ab" AND
    • all banned sequences of length = 2 starting with "b"
    giving us a set of characters to exclude for third character generation.
  • If the first three characters are "abc", for fourth character generation we check:
    • all banned sequences of length = 4 starting with "abc" AND
    • all banned sequences of length = 3 starting with "bc" AND
    • all banned sequences of length = 2 starting with "c"
    giving us a set of characters to exclude for fourth character generation.

Since Captcha codes are short (usually 4-8 characters), such recursive processing is acceptable performance-wise.

Visual Studio 2008 / .NET 3.5

By default, the .NET 3.5 C# version of the ASP.NET Captcha Code Filtering sample project is installed at:
C:\Program Files\Lanapsoft\BotDetect 3 CAPTCHA Component\Asp.Net\v3.5\WebApp\CaptchaCodeFilteringSample\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 2010 / .NET 4.0 source.

Visual Studio 2005 / .NET 2.0

By default, the .NET 2.0 C# version of the ASP.NET Captcha code filtering sample project is installed at:
C:\Program Files\Lanapsoft\BotDetect 3 CAPTCHA Component\Asp.Net\v2.0\WebApp\CaptchaCodeFilteringSample\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 2010 / .NET 4.0 source.