ASP.NET Membership CAPTCHA VB.NET Code Sample (BotDetect v3.0; deprecated)

The ASP.NET Membership Captcha sample project shows how to integrate BotDetect CAPTCHA validation with standard ASP.NET Membership functionality used in ASP.NET Login and CreateUserWizard controls.

First Time Here?

Check the BotDetect ASP.NET WebForms Captcha Quickstart for key integration steps.

To prevent bots from trying to guess the login info by brute force submission of a large number of common values, the visitor first has to prove they are human (by solving the Captcha), and only then is their username and password submission checked against the authentication data store.

Also, if they enter an invalid username + password combination three times, they have to solve the Captcha again. This prevents attempts in which the attacker would first solve the Captcha themselves, and then let a bot brute-force the authentication info.

To keep the example code simple, the sample doesn't access a data store to authenticate the user, but accepts all logins with usernames and passwords at least 5 characters long as valid.

And to prevent bots from registering user accounts, the Register page Captcha has to be solved before user details are recorded.

  • C#
  • VB.NET

Visual Studio 2013 / .NET 4.5.1

Since ASP.NET Membership has been deprecated in Visual Studio 2013 and replaced with ASP.NET 4.5 WebForms Application Template Captcha code sample.

Visual Studio 2012 / .NET 4.5

By default, the .NET 4.5 VB.NET version of the ASP.NET Membership Captcha sample project is installed at:
C:\Program Files\Lanapsoft\BotDetect 3 CAPTCHA Component\Asp.Net\v4.5\WebApp\AspNetMembershipCaptchaSample\VBNet

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 VB.NET version of the ASP.NET Membership Captcha sample project is installed at:
C:\Program Files\Lanapsoft\BotDetect 3 CAPTCHA Component\Asp.Net\v4.0\WebApp\AspNetMembershipCaptchaSample\VBNet

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="VB" AutoEventWireup="true"  CodeFile="Default.aspx.vb" 
  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 ASP.NET Membership Sample</title>
  <link type="text/css" rel="Stylesheet" href="StyleSheet.css" />
</head>
<body>
<form id="form1" runat="server">
  <h1>BotDetect CAPTCHA ASP.NET Membership Sample</h1>
  <fieldset>
    <legend>Page protected with ASP.NET authentication</legend>
    <p>This page can only be seen after successful Captcha validation 
    and username/password authentication.</p>
    <asp:LinkButton Text="Sign out" runat="server" ID="SignOutButton" 
    OnClick="SignOutButton_Click"></asp:LinkButton>
  </fieldset>
</form>
</body>
</html>

This page has no special code, but is meant to only be seen by authenticated users. It will be displayed to users who pass both the Captcha validation and the username / password authentication.

Default.aspx.vb

Partial Class _Default
    Inherits System.Web.UI.Page

    Protected Sub SignOutButton_Click(ByVal sender As Object, ByVal e 
    As System.EventArgs) Handles SignOutButton.Click
        FormsAuthentication.SignOut()
        Response.Redirect("Default.aspx?ref=signout", True)
    End Sub
End Class

Login.aspx

<%@ Page Language="VB" AutoEventWireup="true" CodeFile="Login.aspx.vb" 
Inherits="Login" %>

<!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 runat="server">
  <title>Login</title>
  <link type="text/css" rel="Stylesheet" href="StyleSheet.css" />
</head>
<body>
<form id="form1" runat="server">
  <h1>BotDetect CAPTCHA ASP.NET Membership Sample</h1>
  <fieldset>
    <legend>CAPTCHA Validation in a <code>Login</code> control</legend>
    <asp:Login ID="SampleLogin" runat="server" 
    OnAuthenticate="SampleLogin_Authenticate">
      <LayoutTemplate>
        <table border="0" cellpadding="1" cellspacing="0" 
        style="border-collapse:collapse;">
          <tr>
            <td>
              <table border="0" cellpadding="0">
                <tr>
                  <td align="center" colspan="2">Log In</td>
                </tr>
                <tr>
                  <td align="right" width="185">
                    <asp:Label ID="UserNameLabel" runat="server" 
                    AssociatedControlID="UserName">Username:</asp:
                    Label>
                  </td>
                  <td>
                    <asp:TextBox ID="UserName" runat="server"></asp:
                    TextBox>
                    <asp:RequiredFieldValidator ID="UserNameRequired" 
                    runat="server" ControlToValidate="UserName" 
                    ErrorMessage="User Name is required." 
                    ToolTip="User Name is required." 
                    ValidationGroup="SampleLogin">*</asp:
                    RequiredFieldValidator>
                  </td>
                </tr>
                <tr>
                  <td align="right">
                    <asp:Label ID="PasswordLabel" runat="server" 
                    AssociatedControlID="Password">Password:</asp:
                    Label>
                  </td>
                  <td>
                    <asp:TextBox ID="Password" runat="server" 
                    TextMode="Password"></asp:TextBox>
                    <asp:RequiredFieldValidator ID="PasswordRequired" 
                    runat="server" ControlToValidate="Password" 
                    ErrorMessage="Password is required." 
                    ToolTip="Password is required." 
                    ValidationGroup="SampleLogin">*</asp:
                    RequiredFieldValidator>
                  </td>
                </tr>
                <tr>
                  <td colspan="2">
                    <BotDetect:Captcha ID="LoginCaptcha" 
                    ImageSize="150, 50" CodeLength="3" runat="server"
                    /> 
                  </td>
                </tr>
                <tr runat="server" ID="CaptchaRow">
                  <td align="right">
                    <asp:Label ID="CaptchaLabel" runat="server" 
                    AssociatedControlID="CaptchaCodeTextBox">Code:<
                    /asp:Label>
                  </td>
                  <td>
                    <asp:TextBox ID="CaptchaCodeTextBox" 
                    runat="server"></asp:TextBox>
                    <asp:RequiredFieldValidator 
                    ID="CaptchaRequiredValidator" runat="server" 
                    ControlToValidate="CaptchaCodeTextBox" 
                    ErrorMessage="CAPTCHA code is required." 
                    ToolTip="CAPTCHA code is required." 
                    ValidationGroup="SampleLogin">*</asp:
                    RequiredFieldValidator>
                  </td>
                </tr>
                <tr>
                  <td align="center" colspan="2" style="color:Red;">
                    <asp:Literal ID="FailureText" runat="server" 
                    EnableViewState="False"></asp:Literal>
                  </td>
                </tr>
                <tr>
                  <td align="right" colspan="2">
                    <asp:Button ID="LoginButton" runat="server" 
                    CommandName="Login" Text="Log In" 
                    ValidationGroup="SampleLogin" />
                  </td>
                </tr>
              </table>
            </td>
          </tr>
        </table>
      </LayoutTemplate>
    </asp:Login>
    <p><a href="Register.aspx">Register</a></p>
  </fieldset>
</form>
</body>
</html>

The <BotDetect:Captcha> control is added to the Login form below the username and password fields. An <asp:RequiredFieldValidator> is added and connected with the Captcha code textbox, to warn users not to submit the form without entering the Captcha code.

Login.aspx.vb

Imports BotDetect.Web.UI

Partial Class Login
    Inherits System.Web.UI.Page

    Protected Sub SampleLogin_Authenticate(ByVal sender As Object, 
    ByVal e As System.Web.UI.WebControls.AuthenticateEventArgs)
        Dim CaptchaCodeTextBox As TextBox = TryCast(SampleLogin.
        FindControl("CaptchaCodeTextBox"), TextBox)
        Dim LoginCaptcha As Captcha = TryCast(SampleLogin.FindControl(
        "LoginCaptcha"), Captcha)

        'first, validate the Captcha to check we're not dealing with a 
        bot
        If (Not IsHuman) Then
            Dim code As String, isHuman As Boolean
            code = CaptchaCodeTextBox.Text.Trim().ToUpper()
            isHuman = LoginCaptcha.Validate(code)
            CaptchaCodeTextBox.Text = "" ' clear previous user input

            If Not isHuman Then
                SampleLogin.FailureText = "Retype the characters from 
                the image carefully."
                e.Authenticated = False
                Return
            End If

            HideCaptcha() ' hide the CAPTCHA once it's solved

            'only when we're sure the visitor is human, we try to 
            authenticate them
            If Not Membership.ValidateUser(SampleLogin.UserName, 
            SampleLogin.Password) Then
                SampleLogin.FailureText = "Invalid login info."
                e.Authenticated = False

                FailedAuthAttempts = FailedAuthAttempts + 1
                If (ResetFailedAuthAttempts < FailedAuthAttempts) Then
                    ' show the CAPTCHA again if the user enters 
                    invalid authentication
                    ' info three times in a row
                    ShowCaptcha()
                End If

                Return
            End If
        End If

        e.Authenticated = True
    End Sub

    Protected Sub HideCaptcha()
        Dim LoginCaptcha As Captcha = TryCast(SampleLogin.FindControl(
        "LoginCaptcha"), Captcha)
        Dim CaptchaRow As HtmlControl = TryCast(SampleLogin.
        FindControl("CaptchaRow"), HtmlControl)

        CaptchaRow.Visible = False
        LoginCaptcha.Visible = False
    End Sub

    Protected Sub ShowCaptcha()
        Dim LoginCaptcha As Captcha = TryCast(SampleLogin.FindControl(
        "LoginCaptcha"), Captcha)
        Dim CaptchaRow As HtmlControl = TryCast(SampleLogin.
        FindControl("CaptchaRow"), HtmlControl)

        IsHuman = False
        FailedAuthAttempts = 0
        CaptchaRow.Visible = True
        LoginCaptcha.Visible = True
    End Sub

    ' flag showing the user successfully passed the CAPTCHA test
    Protected Property IsHuman() As Boolean
        Get
            Dim result As Boolean = False
            Try
                If (Nothing <> Session("IsHuman")) Then
                    result = CBool(Session("IsHuman"))
                End If
            Catch e As InvalidCastException
            End Try

            Return result
        End Get

        Set(ByVal value As Boolean)
            Session("IsHuman") = value
        End Set
    End Property

    Protected Const ResetFailedAuthAttempts As Integer = 3

    ' failed authentication attempt counter
    Protected Property FailedAuthAttempts() As Integer
        Get
            Dim count As Integer = 0
            Try
                If (Nothing <> Session("FailedAuthAttempts")) Then
                    count = CInt(Session("FailedAuthAttempts"))
                End If
            Catch e As InvalidCastException
            End Try

            Return count
        End Get

        Set(ByVal value As Integer)
            Session("FailedAuthAttempts") = value
        End Set
    End Property

End Class

Since we want to process login attempts as they are submitted, we handle the SampleLogin_Authenticate event. To get the Captcha code textbox and Captcha control instances, we have to use SampleLogin.FindControl() calls (as they can't be accessed directly by ID in this event handler).

Since we want to remember when the user correctly solved the Captcha (so they don't have to immediately solve another one if the fail the first authentication attempt), we keep it in the IsHuman property wrapping Session persistence. And since we want to reset the Captcha status after a number of failed authentications (3 by default, as defined in the ResetFailedAuthAttempts constant), we keep the related counter in the FailedAuthAttempts property.

This allows us to implement the proper Login form workflow:

  • The user must first solve the Captcha to prove they are human. This keeps the bots away from the Membership provider, both conserving its resources and improving its security (since usernames and passwords will not be forwarded to the underlying data store if the Captcha is not solved first).
  • When the user has proven they are human, they get 3 authentication attempts without new Captcha tests, which allows them to remember the right combination in most cases.
  • If the user fails three authentication requests, they are shown a new Captcha which they must solve before continuing. This throttles authentication access, ensuring username + password combinations cannot be brute-forced, while real human users get theoretically unlimited authentication attempts (as long as they don't mind solving further Captchas).

Register.aspx

<%@ Page Language="VB" AutoEventWireup="true" CodeFile="Register.aspx.
vb" Inherits="Register" %>

<!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 runat="server">
  <title>Register</title>
  <link type="text/css" rel="Stylesheet" href="StyleSheet.css" />
</head>
<body>
<form id="form1" runat="server">
  <h1>BotDetect CAPTCHA ASP.NET Membership Sample</h1>
  <fieldset>
    <legend>CAPTCHA Validation in a <code>CreateUserWizard</code> 
    control</legend>
    <asp:CreateUserWizard ID="RegisterUser" runat="server" 
    OnNextButtonClick="RegisterUser_NextButtonClick" 
    ActiveStepIndex="0">
      <WizardSteps>
        <asp:CreateUserWizardStep runat="server">
          <ContentTemplate>
            <table border="0">
              <tr>
                <td align="center" colspan="2">Sign Up for Your New 
                Account</td>
              </tr>
              <tr>
                <td align="right" width="185">
                  <asp:Label ID="UserNameLabel" runat="server" 
                  AssociatedControlID="UserName">Username:</asp:Label>
                </td>
                <td>
                  <asp:TextBox ID="UserName" runat="server"></asp:
                  TextBox>
                  <asp:RequiredFieldValidator ID="UserNameRequired" 
                  runat="server" ControlToValidate="UserName" 
                  ErrorMessage="User Name is required." ToolTip="User 
                  Name is required." ValidationGroup="RegisterUser">*<
                  /asp:RequiredFieldValidator>
                </td>
              </tr>
              <tr>
                <td align="right">
                  <asp:Label ID="PasswordLabel" runat="server" 
                  AssociatedControlID="Password">Password:</asp:Label>
                </td>
                <td>
                  <asp:TextBox ID="Password" runat="server" 
                  TextMode="Password"></asp:TextBox>
                  <asp:RequiredFieldValidator ID="PasswordRequired" 
                  runat="server" ControlToValidate="Password" 
                  ErrorMessage="Password is required." 
                  ToolTip="Password is required." 
                  ValidationGroup="RegisterUser">*</asp:
                  RequiredFieldValidator>
                </td>
              </tr>
              <tr>
                <td align="right">
                  <asp:Label ID="ConfirmPasswordLabel" runat="server" 
                  AssociatedControlID="ConfirmPassword">Confirm 
                  Password:</asp:Label>
                </td>
                <td>
                  <asp:TextBox ID="ConfirmPassword" runat="server" 
                  TextMode="Password"></asp:TextBox>
                  <asp:RequiredFieldValidator 
                  ID="ConfirmPasswordRequired" runat="server" 
                  ControlToValidate="ConfirmPassword" 
                  ErrorMessage="Confirm Password is required." 
                  ToolTip="Confirm Password is required." 
                  ValidationGroup="RegisterUser">*</asp:
                  RequiredFieldValidator>
                </td>
              </tr>
              <tr>
                <td align="center" colspan="2">
                  <asp:CompareValidator ID="PasswordCompare" 
                  runat="server" ControlToCompare="Password" 
                  ControlToValidate="ConfirmPassword" 
                  Display="Dynamic"  ErrorMessage="The Password and 
                  Confirmation Password must match." 
                  ValidationGroup="RegisterUser"></asp:
                  CompareValidator>
                </td>
              </tr>
              <tr>
                <td align="right">
                  <asp:Label ID="EmailLabel" runat="server" 
                  AssociatedControlID="Email">E-mail:</asp:Label>
                </td>
                <td>
                  <asp:TextBox ID="Email" runat="server"></asp:TextBox>
                  <asp:RequiredFieldValidator ID="EmailRequired" 
                  runat="server" ControlToValidate="Email" 
                  ErrorMessage="E-mail is required." ToolTip="E-mail 
                  is required." ValidationGroup="RegisterUser">*</asp:
                  RequiredFieldValidator>
                </td>
              </tr>
              <tr>
                <td colspan="2">
                  <BotDetect:Captcha ID="RegisterCaptcha" 
                  ImageSize="150, 50" CodeLength="3" runat="server" />
                </td>
              </tr>
              <tr>
                <td align="right">
                  <asp:Label ID="CaptchaLabel" runat="server" 
                  AssociatedControlID="CaptchaCodeTextBox">Code:</asp:
                  Label>
                </td>
                <td>
                  <asp:TextBox ID="CaptchaCodeTextBox" runat="server"><
                  /asp:TextBox>
                  <asp:RequiredFieldValidator 
                  ID="CaptchaRequiredValidator" runat="server" 
                  ControlToValidate="CaptchaCodeTextBox" 
                  ErrorMessage="CAPTCHA code is required." 
                  ToolTip="CAPTCHA code is required." 
                  ValidationGroup="RegisterUser">*</asp:
                  RequiredFieldValidator>
                </td>
              </tr>
              <tr>
                <td align="center" colspan="2" style="color:Red;">
                  <asp:Literal ID="InvalidCaptchaInput" runat="server" 
                  EnableViewState="False" Visible="False" Text="Retype 
                  the characters from the image carefully."></asp:
                  Literal>
                </td>
                <td align="center" colspan="2" style="color:Red;">
                  <asp:Literal ID="ErrorMessage" runat="server" 
                  EnableViewState="False"></asp:Literal>
                </td>
              </tr>
            </table>
          </ContentTemplate>
        </asp:CreateUserWizardStep>
        <asp:CompleteWizardStep runat="server">
          <ContentTemplate>
            <table border="0">
              <tr>
                <td align="center" colspan="2">Complete</td>
              </tr>
              <tr>
                <td>Your account has been successfully created.</td>
              </tr>
              <tr>
                <td align="right" colspan="2">
                  <p><a href="Default.aspx">Continue</a></p>
                </td>
              </tr>
            </table>
          </ContentTemplate>
        </asp:CompleteWizardStep>
      </WizardSteps>
    </asp:CreateUserWizard>
    <p><a href="Login.aspx">Login</a></p>
  </fieldset>
</form>
</body>
</html>

To protect the user registration field from automated submissions, a <BotDetect:Captcha> control is added to the CreateUserWizard template.

Register.aspx.vb

Imports BotDetect.Web.UI

Partial Class Register
    Inherits System.Web.UI.Page

    Protected Sub RegisterUser_NextButtonClick(ByVal sender As Object, 
    ByVal e As System.Web.UI.WebControls.WizardNavigationEventArgs)

        If e.CurrentStepIndex = 0 Then 'CreateUserStep

            ' get control references
            Dim RegisterCaptcha As Captcha = TryCast(RegisterUser.
            CreateUserStep.ContentTemplateContainer.FindControl(
            "RegisterCaptcha"), Captcha)
            Dim CaptchaCodeTextBox As TextBox = TryCast(RegisterUser.
            CreateUserStep.ContentTemplateContainer.FindControl(
            "CaptchaCodeTextBox"), TextBox)
            Dim CaptchaIncorrect As Literal = TryCast(RegisterUser.
            CreateUserStep.ContentTemplateContainer.FindControl(
            "InvalidCaptchaInput"), Literal)

            ' validate the Captcha to check we're not dealing with a 
            bot
            Dim code As String, isHuman As Boolean
            code = CaptchaCodeTextBox.Text.Trim().ToUpper()
            isHuman = RegisterCaptcha.Validate(code)
            CaptchaCodeTextBox.Text = "" ' clear previous user input

            If isHuman Then
                CaptchaIncorrect.Visible = True
                e.Cancel = True
            Else
                CaptchaIncorrect.Visible = False
            End If
        End If

    End Sub
End Class

To process user creation attempts, we handle the RegisterUser_NextButtonClick event and make sure the code is executed during the first wizard step where Captcha protection was added (If e.CurrentStepIndex = 0).

We use ContentTemplateContainer.FindControl() calls to get all necessary control references, and simply cancel account creation unless Captcha validation succeeds.

Web.config

<?xml version="1.0"?>
<configuration xmlns="http://schemas.microsoft.com/.
NetConfiguration/v2.0">
  <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>
      <namespaces>
        <add namespace="BotDetect"/>
        <add namespace="BotDetect.Web"/>
        <add namespace="BotDetect.Web.UI"/>
      </namespaces>
    </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=""/>
    <customErrors mode="RemoteOnly"></customErrors>
    <!-- Forms authentication -->
    <authentication mode="Forms">
      <forms loginUrl="Login.aspx"/>
    </authentication>
    <!-- Deny access to all pages to unauthorized users -->
    <authorization>
      <deny users="?"/>
      <allow users="*"/>
    </authorization>
    <!-- Membership provider -->
    <membership defaultProvider="MockMembershipProvider">
      <providers>
        <add name="MockMembershipProvider" applicationName="/" 
        type="Sample.MockMembershipProvider"/>
      </providers>
    </membership>
  </system.web>
  <!-- Allow unauthorized access to the Login page -->
  <location path="Login.aspx">
    <system.web>
      <authorization>
        <allow users="*"/>
      </authorization>
    </system.web>
  </location>
  <!-- Allow unauthorized access to the Register page -->
  <location path="Register.aspx">
    <system.web>
      <authorization>
        <allow users="*"/>
      </authorization>
    </system.web>
  </location>
  <!-- Allow unauthorized access to BotDetect Captcha images and 
  sounds -->
  <location path="BotDetectCaptcha.ashx">
    <system.web>
      <authorization>
        <allow users="*"/>
      </authorization>
    </system.web>
  </location>
  <!-- Allow unauthorized access to the Stylesheet -->
  <location path="StyleSheet.css">
    <system.web>
      <authorization>
        <allow users="*"/>
      </authorization>
    </system.web>
  </location>
  <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>

Besides the usual BotDetect-related web.config changes (Captcha HttpHandler registration, ASP.NET Session state configuration, and BotDetect tag prefix registration), the authentication and authorization elements define access restrictions, while the location elements specify exceptions to those restrictions. In this case, unauthorized users can only access the Login and Register pages and BotDetect Captcha paths.

To keep the sample as simple as possible, we use the MockMembershipProvider instead of a real MembershipProvider. It doesn't access any data store to verify the user's credentials, but considers all authorization requests with usernames and passwords longer than 5 characters as valid. Since it doesn't affect Captcha protection and validation logic, MockMembershipProvider is not shown (but is included in the sample installation).

Visual Studio 2008 / .NET 3.5

By default, the .NET 3.5 VB.NET version of the ASP.NET Membership Captcha sample project is installed at:
C:\Program Files\Lanapsoft\BotDetect 3 CAPTCHA Component\Asp.Net\v3.5\WebApp\AspNetMembershipCaptchaSample\VBNet

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 VB.NET version of the ASP.NET Membership Captcha sample project is installed at:
C:\Program Files\Lanapsoft\BotDetect 3 CAPTCHA Component\Asp.Net\v2.0\WebApp\AspNetMembershipCaptchaSample\VBNet

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.


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.