BotDetect ASP.NET 2.0 CAPTCHA Validation VB.NET Code Sample

The CAPTCHA validation sample contains the basic code required to add a CAPTCHA control to an ASP.NET page and validate the user input. It can be used as a starting point when you are first learning how to use BotDetect CAPTCHA, and is equivalent to the result you will get if you are following the How To use BotDetect ASP.NET CAPTCHA in Visual Studio 2005 instructions.

Sample Project Location

By default, this sample project is installed at
C:\Program Files\Lanapsoft\BotDetect\ASP.NET 2.0\v2.0\Samples\VBNetBotDetect2Demo\.

You can also run it from the Start Menu:
Programs > Lanapsoft > BotDetect > ASP.NET 2.0 > v2.0 > Samples > VB.NET BotDetect Demo Preview.

Default.aspx

Full Source Code Listing

<%@ Page Language="VB" AutoEventWireup="false" 
  CodeFile="Default.aspx.vb" Inherits="_Default" %>

<%@ Register Assembly="Lanap.BotDetect" Namespace="Lanap.BotDetect" 
  TagPrefix="BotDetect" %>

<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title>BotDetect Demo</title>
    <link type='text/css' rel='Stylesheet' href='StyleSheet.css' />
</head>
<body>
    <form id="form1" runat="server">
    <fieldset id="Preview">
        <legend>
            <span id="PreviewLegend">CAPTCHA Preview</span>
        </legend>
        <div id="PromptDiv">
            <span id="Prompt">Type the characters you see in 
              the picture</span>
        </div>
        <div id="CaptchaDiv">
            <BotDetect:Captcha ID="SampleCaptcha" runat="server" />
        </div>
        <div id="ValidationDiv">
            <asp:TextBox ID="CodeTextBox" runat="server">
            </asp:TextBox>
            <asp:Button ID="ValidateButton" runat="server" />
            <asp:Label ID="MessageCorrectLabel" runat="server">
            </asp:Label>
            <asp:Label ID="MessageIncorrectLabel" runat="server">
            </asp:Label>
        </div>
    </fieldset>
    <div id="Note">
        <span>NOTE: the Trial version will use "LANAP" instead of a 
          random code in 50% of renderings.</span>
    </div>
    </form>
</body>
</html>

Explanation

Lines required to add the BotDetect CAPTCHA control to the ASP.NET form are bolded. To use the <BotDetect:Captcha> control, we must first register the Lanap.BotDetect.dll assembly using the <%@Register %> directive.

The form also contains an <asp:TextBox> for the user input, an <asp:Button> to submit the page, and a pair of <asp:Label> controls which are used to show the CAPTCHA validation result.

The rest of the file is either generated by Visual Studio 2005 by default, or just defines the layout and visual presentation of the page.

Default.aspx.vb

Full Source Code Listing

Partial Class _Default
    Inherits System.Web.UI.Page

    Protected Sub Page_PreRender(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles MyBase.PreRender

        ' initial page setup
        If (Not IsPostBack) Then
            'set control text
            ValidateButton.Text = "Validate"
            MessageCorrectLabel.Text = "Correct!"
            MessageIncorrectLabel.Text = "Incorrect!"

            'these messages are shown only after validation
            MessageCorrectLabel.Visible = False
            MessageIncorrectLabel.Visible = False
        End If

        CodeTextBox.Attributes.Add("onkeyup", _
            "this.value = this.value.toLowerCase();")

        If (IsPostBack) Then
            'validate the input code, and show 
            'the appropriate message 
            Dim code As String = CodeTextBox.Text.Trim().ToUpper()

            If (SampleCaptcha.Validate(code)) Then
                MessageCorrectLabel.Visible = True
                MessageIncorrectLabel.Visible = False
            Else
                MessageCorrectLabel.Visible = False
                MessageIncorrectLabel.Visible = True
            End If

            'clear previous user code input
            CodeTextBox.Text = ""
        End If

    End Sub

End Class

Explanation

Form processing is done in the Page_PreRender event handler, so all individual control events are executed before the CAPTCHA validation. If you want to validate the CAPTCHA before individual control events, you can move the code to the Page_Load event handler.

Also, the processing is not done in the ValidateButton_Click handler on purpose, in case there are multiple controls which can submit the page – we want to validate the CAPTCHA regardless of what caused the page to submit. Not to mention that most bots will not submit the page by clicking the button, but by simply constructing the POST request data, which might or might not include the "control which caused the postback" part, responsible for triggering the button click event. Checking the CAPTCHA on each page load ensures proper CAPTCHA security in all cases.

On the first page load ( if (!IsPostBack) ), the button and label controls are initialized, and the CAPTCHA validation is skipped, because the user didn't have a chance to solve it yet.

On each page load, we add a small JavaScript fragment to the textbox onkeyup client-side event handler, so the user input is immediately lowercased during typing. This serves to communicate the fact that the CAPTCHA code is not case-sensitive to the user.

When the page is submitted ( if (IsPostBack) ), we forward the user input to the Captcha.Validate() method. In this simplified sample, we use the validation result just to display a message, and always show a new CAPTCHA. In most use cases, you will show a new CAPTCHA only if the user didn't solve the previous one correctly, and execute the protected code fragment (user registration, comment recording, etc.) if the CAPTCHA was solved correctly.

If you redirect the user to a different page upon successful CAPTCHA completion, and you want to protect such pages as well, it might be a good idea to set a Session variable (for example, Session["IsHuman"] = true), and check it on subsequent pages. Otherwise, some bots could be written to skip the CAPTCHA-protected page and go to those later pages directly, bypassing some of the protection.

Finally, since a new CAPTCHA image is shown on each page load and each CAPTCHA code can only be validated once (regardless of the validation result), the user input should always be cleared after the CAPTCHA validation.

Web.config

Full Source Code Listing

<?xml version="1.0"?>
<!-- 
    Note: As an alternative to hand editing this file you can use the 
    web admin tool to configure settings for your application. Use
    the Website->Asp.Net Configuration option in Visual Studio.
    A full list of settings and comments can be found in 
    machine.config.comments usually located in 
    \Windows\Microsoft.Net\Framework\v2.x\Config 
-->
<configuration>
  <connectionStrings/>
  <system.web>
    <httpHandlers>
      <add verb="*" path="LanapCaptcha.aspx" 
        type="Lanap.BotDetect.CaptchaHandler, Lanap.BotDetect"/>
    </httpHandlers>
    <sessionState mode="InProc" cookieless="AutoDetect" timeout="20" 
      sessionIDManagerType="Lanap.BotDetect.Persistence.
      CustomSessionIDManager, Lanap.BotDetect" />
    <!-- 
      Set compilation debug="true" to insert debugging 
      symbols into the compiled page. Because this 
      affects performance, set this value to true only 
      during development.
    -->
    <compilation debug="false">
      <assemblies>
        <add assembly="System.Design, Version=2.0.0.0, 
          Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
      </assemblies>
    </compilation>
    <pages>
      <namespaces>
        <clear/>
        <add namespace="System"/>
        <add namespace="System.Collections"/>
        <add namespace="System.Collections.Specialized"/>
        <add namespace="System.Configuration"/>
        <add namespace="System.Text"/>
        <add namespace="System.Text.RegularExpressions"/>
        <add namespace="System.Web"/>
        <add namespace="System.Web.Caching"/>
        <add namespace="System.Web.SessionState"/>
        <add namespace="System.Web.Security"/>
        <add namespace="System.Web.Profile"/>
        <add namespace="System.Web.UI"/>
        <add namespace="System.Web.UI.WebControls"/>
        <add namespace="System.Web.UI.WebControls.WebParts"/>
        <add namespace="System.Web.UI.HtmlControls"/>
      </namespaces>
    </pages>
    <!--
      The <authentication> section enables configuration 
      of the security authentication mode used by 
      ASP.NET to identify an incoming user. 
    -->
    <authentication mode="None"/>
    <!--
      The <customErrors> section enables configuration 
      of what to do if/when an unhandled error occurs 
      during the execution of a request. Specifically, 
      it enables developers to configure html error pages 
      to be displayed in place of a error stack trace.

      <customErrors mode="RemoteOnly" 
        defaultRedirect="GenericErrorPage.htm">
        <error statusCode="403" redirect="NoAccess.htm" />
        <error statusCode="404" redirect="FileNotFound.htm" />
      </customErrors>
    -->
  </system.web>
  <system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <handlers>
      <remove name="LanapCaptchaHandler" />
      <add name="LanapCaptchaHandler" preCondition="integratedMode" 
        verb="*" path="LanapCaptcha.aspx" 
        type="Lanap.BotDetect.CaptchaHandler, Lanap.BotDetect" />
    </handlers>
  </system.webServer>
</configuration>

Explanation

Lines neccesary for BotDetect CAPTCHA to function properly have been bolded, other lines are all standard values generated by Visual Studio 2005 by default.

The <httpHandlers> element registers the path used for CAPTCHA image and sound requests for processing by Lanap.BotDetect.dll code. The <system.webServer> element serves the same purpose, but is used only by IIS 7.0 machines configured to integrate the ASP.NET pipeline in the IIS process.

The validateIntegratedModeConfiguration="false" declaration ensures that the web.config file can be processed by by older versions of IIS (5.1, 6.0) as well as the 7.0 version. Since the HttpHandler registration syntax differs between IIS versions and ASP.NET integration modes, having both elements makes the web.config file compatible with all supported IIS versions.

The <sessionState> element declares the persistence mechanism used by BotDetect to keep the CAPTCHA codes and settings for each user. Different Session State modes, providers and timeouts can be used, but the sessionIDManagerType element is required to fix a bug caused by Windows Media Player 11 when requesting audio CAPTCHAs (as explained in this FAQ item). Also, special care should be taken if you are running multiple load-balanced servers, as explained in this FAQ item.

The cookieless element value is set to allow CAPTCHAs to be solved even by users who have cookies disables in their browser. However, note that for such users all Urls in the application will be rewritten to contain the session identifier, making them dynamic. This can cause problems with various crawlers, which don't support cookies as a rule.

One common side-effect of this setting is that Google and other Search Engines might keep multiple copies of the CAPTCHA-protected page in their index (since they are always redirected to a different Url). If you want the CAPTCHA-protected page to be indexed by Search Engines, you should use the cookieless="false" setting, or find a way to use cookieless Sessions for human users, but not for crawlers (via the User Agent string, the App_Browsers .browser files, etc.)