ASP.NET CAPTCHA Troubleshooting C# Code Sample

The ASP.NET Captcha troubleshooting sample project shows how to use BotDetect CAPTCHA built-in error logging and Captcha event tracing, using the BotDetect Troubleshooting utility based on log4net.

First Time Here?

Check the BotDetect Developer Crash Course for key integration steps.

The logging requires the <captchaLogging> element and BotDetectTroubleshooting Module registration in the web.config file, as well as the log4net.config file defining log4net settings (in this case, logging to simple text files).

Such logging techniques can be used as a foundation for effective diagnosis and resolution of any BotDetect issues you might encounter on your servers.

The sample demonstrates the effects of following the How To Troubleshoot BotDetect ASP.NET CAPTCHA Issues guide.

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 troubleshooting sample project is installed at:
C:\Program Files\Lanapsoft\BotDetect 3 CAPTCHA Component\Asp.Net\v4.5\WebApp\CaptchaTroubleshootingSample\ 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 troubleshooting sample project is installed at:
C:\Program Files\Lanapsoft\BotDetect 3 CAPTCHA Component\Asp.Net\v4.0\WebApp\CaptchaTroubleshootingSample\ 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 Transitional//EN" "http:
//www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
  <title>BotDetect ASP.NET CAPTCHA Troubleshooting Sample</title>
  <link type="text/css" rel="Stylesheet" href="StyleSheet.css" />
</head>
<body>
<form id="form1" runat="server">
  <h1>BotDetect ASP.NET CAPTCHA Troubleshooting Sample</h1>
  <fieldset id="TroubleshootingDebug">
    <legend>CAPTCHA Debug Logging</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>
    <p class="validationTroubleshooting">A detailed trace of all 
    CAPTCHA events will be logged to the 'debug.txt' file in the 
    sample folder.</p>
    <div class="troubleshooting">
      <asp:Label ID="DebugLabel" runat="server"></asp:Label>
    </div>
  </fieldset>
  <fieldset id="TroubleshootingError">
    <legend>CAPTCHA Error Logging</legend>
    <p class="troubleshooting">Clicking 'Simulate Error' will throw a 
    fake BotDetect CAPTCHA exception and log it to the 'error.txt' 
    file in the sample folder.</p>
    <asp:Button ID="CauseErrorButton" runat="server" 
    OnClick="CauseErrorButton_Click" />
    <div class="troubleshooting">
      <asp:Label ID="ErrorLabel" runat="server"></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;

using BotDetect;
using BotDetect.Web;
using BotDetect.Web.UI;

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;

            CauseErrorButton.Text = "Simulate error";
            ErrorLabel.Text = "An error has been generated. Please 
            check the 'error.txt' file.";

            DebugLabel.Text = "A validation attempt has been logged. 
            Please check the 'debug.txt' file.";
            DebugLabel.Visible = false;
        }

        if (null != Session["error"])
        {
            ErrorLabel.Visible = true;
            CaptchaCorrectLabel.Visible = false;
            CaptchaIncorrectLabel.Visible = false;
            Session["error"] = null;
            DebugLabel.Visible = false;
        }
        else
        {
            ErrorLabel.Visible = false;
        }

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

            DebugLabel.Visible = true;
        }
    }

    protected void CauseErrorButton_Click(object sender, EventArgs e)
    {
        Session["error"] = true;
        throw new CaptchaControlException("Simulated exception");
    }
}

Global.asax

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

<script runat="server">

    void Application_Start(object sender, EventArgs e) 
    {
        // Code that runs on application startup

    }
    
    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
        
        // since we log the errors using our handler, 
        // they don't need to be shown to the client
        
        Response.Redirect("Default.aspx");
    }

    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>

log4net.config

<?xml version="1.0"?>

<!-- This section contains the log4net configuration settings -->
<log4net debug="false">

  <!-- Errors are logged to a 'error.txt' file -->
  <appender name="ErrorFileAppender" type="log4net.Appender.
  FileAppender">
    <file value="error.txt" />
    <appendToFile value="true" />
    <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
    <layout type="log4net.Layout.PatternLayout,log4net">
      <conversionPattern value="%date [%thread] %type - 
      %n%n%message%n%n" />
    </layout>
  </appender>

  <!-- Error logging is enabled, comment-out to disable -->
  <logger name="ErrorLogger">
    <level value="ERROR" />
    <appender-ref ref="ErrorFileAppender" />
  </logger>

  
  <!-- Debug info is logged to a 'debug.txt' file -->
  <appender name="DebugFileAppender" type="log4net.Appender.
  FileAppender">
    <file value="debug.txt" />
    <appendToFile value="true" />
    <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
    <layout type="log4net.Layout.PatternLayout,log4net">
      <conversionPattern value="%date [%thread] %type - 
      %n%n%message%n%n" />
    </layout>
  </appender>

  <!-- Debug logging is enabled, comment-out to disable -->
  <logger name="DebugLogger">
    <level value="DEBUG" />
    <appender-ref ref="DebugFileAppender" />
  </logger>

</log4net>

Web.config

<?xml version="1.0"?>
<configuration xmlns="http://schemas.microsoft.com/.
NetConfiguration/v2.0">
  <configSections>
    <!-- Register the log4net configuration section -->
    <section name="log4net" type="log4net.Config.
    Log4NetConfigurationSectionHandler, log4net" 
    requirePermission="false"/>
    <!-- Register the BotDetect configuration section -->
    <section name="botDetect" 
	type="BotDetect.Configuration.BotDetectConfigurationSection, BotDetect" 
    requirePermission="false"/>
  </configSections>
  <!-- log4net settings are loaded from a separate config file -->
  <log4net configSource="log4net.config"/>
  <!-- BotDetect Captcha settings can be configured in this section -->
  <botDetect>
    <!-- Register the log4net BotDetect logging provider -->
    <captchaLogging errorLoggingEnabled="true" traceEnabled="true" 
    eventFilter=".*" 
	loggingProvider="BotDetect.Logging.Log4NetLoggingProvider, 
	BotDetect.Troubleshooting"/>
  </botDetect>
  <system.web>
    <httpHandlers>
      <!-- Register the HttpHandler used for BotDetect Captcha 
      requests -->
      <add verb="GET" path="BotDetectCaptcha.ashx" 
	  type="BotDetect.Web.CaptchaHandler, BotDetect"/>
    </httpHandlers>
    <httpModules>
      <!-- Register the HttpModule used for BotDetect error logging (
      IIS 5.0, 5.1, 6.0) -->
      <add name="BotDetectTroubleshootingModule" 
	  type="BotDetect.Web.CaptchaTroubleshootingModule, BotDetect"/>
    </httpModules>
    <!-- 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"/>
  </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>
    <modules>
      <!-- Register the HttpModule used for BotDetect error logging (
      IIS 7.0+) -->
      <remove name="BotDetectTroubleshootingModule"/>
      <add name="BotDetectTroubleshootingModule" 
      preCondition="integratedMode" 
	  type="BotDetect.Web.CaptchaTroubleshootingModule, BotDetect"/>
    </modules>
  </system.webServer>
</configuration>

Visual Studio 2008 / .NET 3.5

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