ASP.NET WebForms Application Template CAPTCHA VB.NET Code Example

First Time Here?

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

The ASP.NET WebForms application template Captcha Simple API example project shows how to add BotDetect CAPTCHA protection to the registration form included in the default ASP.NET Web Forms Application project template coming with Visual Studio.

The example shows how to include BotDetect CAPTCHA validation in new user data validation for the example Register form

The example also shows how to complement server-side CAPTCHA validation with client-side Ajax CAPTCHA validation using ASP.NET unobtrusive validation applied to all form fields.

Download the BotDetect ASP.NET CAPTCHA Component and run this example
  • C#
  • VB.NET

Visual Studio 2015 / Visual Studio 2013 / .NET 4.6 / .NET 4.5.1

The Visual Studio 2015 / 2013 WebForms application Captcha Simple API example project shows how to add BotDetect CAPTCHA protection to the registration form included in the default ASP.NET Web Forms Application project template coming with Visual Studio 2015 / 2013 (File > New Project > Installed > Templates > Visual C# > Web > ASP.NET Web Application > Web Forms).

Since the Register form uses ASP.NET Identity user management, the example shows how to include BotDetect CAPTCHA validation in new user data validation (see Account/Register.aspx and Account/Register.aspx.cs source code).

The example also shows how to complement server-side CAPTCHA validation with client-side Ajax CAPTCHA validation using ASP.NET 4.6 / 4.5.1 unobtrusive validation applied to all form fields (Scripts/WebForms/WebUICaptchaValidation.js).

Installed Location

By default, the C# version of the ASP.NET WebForms Application Template Captcha Simple API example project is installed at:
C:\Program Files\Captcha Inc\BotDetect 4 CAPTCHA Component\Asp.Net\.NET\WebApp\SimpleAPI\WebFormsVS2015AppTemplateExample\VBNet

C:\Program Files\Captcha Inc\BotDetect 4 CAPTCHA Component\Asp.Net\.NET\WebApp\SimpleAPI\WebFormsVS2013AppTemplateExample\VBNet

You can also run it from the BotDetect Start Menu:
Programs > Captcha Inc > BotDetect 4 CAPTCHA Component > ASP.NET > ASP.NET Examples > Run .NET Examples

Example Code Files

Account\Register.aspx

<%@ Page Title="Register" Language="vb" AutoEventWireup="false" 
MasterPageFile="~/Site.Master" CodeBehind="Register.aspx.vb" 
Inherits="AspNetWebForms451CaptchaExampleVBNet.Register" %>

<%@ Import Namespace="BotDetect.Web.UI" %>

<%@ Import Namespace="AspNetWebForms451CaptchaExampleVBNet" %>
<%@ Import Namespace="Microsoft.AspNet.Identity" %>
<asp:Content runat="server" ID="BodyContent" ContentPlaceHolderID="MainContent">
  <h2><%: Title %>.</h2>
  <p class="text-danger">
    <asp:Literal runat="server" ID="ErrorMessage" />
  </p>

  <div class="form-horizontal">
    <h4>Create a new account.</h4>
    <hr />

    <div class="col-md-6" id="form-container">

      <asp:ValidationSummary runat="server" CssClass="text-danger" />

      <div class="form-group">
        <asp:Label runat="server" AssociatedControlID="UserNameCtrl" 
        CssClass="col-md-4 control-label">User name</asp:Label>
        <div class="col-md-8">
          <asp:TextBox runat="server" ID="UserNameCtrl" CssClass="form-control" />
          <asp:RequiredFieldValidator runat="server" 
          ControlToValidate="UserNameCtrl"
            CssClass="text-danger" ErrorMessage="The user name field is required. " />
        </div>
      </div>
      <div class="form-group">
        <asp:Label runat="server" AssociatedControlID="Password" CssClass="col-md-4 control-label">Password</asp:Label>
        <div class="col-md-8">
          <asp:TextBox runat="server" ID="Password" TextMode="Password" 
          CssClass="form-control" />
          <asp:RequiredFieldValidator runat="server" 
          ControlToValidate="Password"
            CssClass="text-danger" ErrorMessage="The password field is required." />
        </div>
      </div>
      <div class="form-group">
        <asp:Label runat="server" AssociatedControlID="ConfirmPassword" 
        CssClass="col-md-4 control-label">Confirm password</asp:Label>
        <div class="col-md-8">
          <asp:TextBox runat="server" ID="ConfirmPassword" TextMode="Password" 
          CssClass="form-control" />
          <asp:RequiredFieldValidator runat="server" 
          ControlToValidate="ConfirmPassword"
            CssClass="text-danger" Display="Dynamic" 
            ErrorMessage="The confirm password field is required." />
          <asp:CompareValidator runat="server" ControlToCompare="Password" 
          ControlToValidate="ConfirmPassword"
            CssClass="text-danger" Display="Dynamic" 
            ErrorMessage="The password and confirmation password do not match." />
        </div>
      </div>
      <!-- Add the controls for CAPTCHA validation to the registration form -->
      <div class="form-group">
        <div class="col-md-offset-4 col-md-8">
          <BotDetect:WebFormsSimpleCaptcha ID="RegisterCaptcha" runat="server" />
        </div>
        <asp:Label runat="server" AssociatedControlID="CaptchaCode" 
        CssClass="col-md-4 control-label">Retype code</asp:Label>
        <div class="col-md-8">
          <asp:TextBox runat="server" ID="CaptchaCode" CssClass="form-control 
          captchaVal" />
          <asp:RequiredFieldValidator ID="CaptchaRequiredValidator" 
          runat="server" ControlToValidate="CaptchaCode"
            CssClass="text-danger" Display="Dynamic" 
            ErrorMessage="Retyping the code from the picture is required." />
          <asp:CustomValidator runat="server" ID="CaptchaValidator" 
          ControlToValidate="CaptchaCode"
            CssClass="text-danger" Display="Dynamic" 
            ErrorMessage="Incorrect code, please try again."
            OnServerValidate="CaptchaValidator_ServerValidate" 
            ClientValidationFunction="ValidateCaptcha" />
        </div>
      </div>
      <div class="form-group" id="form-submit">
        <div class="col-md-offset-4 col-md-8">
          <asp:Button runat="server" OnClick="CreateUser_Click" Text="Register" 
          CssClass="btn btn-default" />
        </div>
      </div>
    </div>
  </div>
</asp:Content>

To show a SimpleCaptcha test on the registration form, we add a <BotDetect:SimpleCaptcha> control and a textbox in which the visitor will type the displayed Captcha code. We also tag this textbox with a special CSS class (captchaVal), so we can attach client-side jQuery validation to it dynamically without knowing its exact ID.

To make the Captcha code a required form field, we add a <asp:RequiredFieldValidator>. For proper SimpleCaptcha validation comparing the user input to the Captcha code stored on the server during image generation, we add a <asp:CustomValidator> associated with the textbox and set its OnServerValidate property to point to a validation function in form code-behind. To allow unobtrusive Ajax SimpleCaptcha validation, we set its ClientValidationFunction to point at the custom Ajax SimpleCaptcha validation script we will define in client-side code.

Account\Register.aspx.vb

Imports Microsoft.AspNet.Identity
Imports Microsoft.AspNet.Identity.EntityFramework
Imports Microsoft.AspNet.Identity.Owin
Imports System
Imports System.Linq
Imports System.Web
Imports System.Web.UI

Partial Public Class Register
  Inherits Page

  Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles 
  Me.Load


  End Sub

  Protected Sub CreateUser_Click(sender As Object, e As EventArgs)
    If Me.IsValid Then
      Dim userName As String = UserNameCtrl.Text
      Dim manager = New UserManager()
      Dim user = New ApplicationUser() With {.UserName = userName}
      Dim result = manager.Create(user, Password.Text)
      If result.Succeeded Then
        IdentityHelper.SignIn(manager, user, isPersistent:=False)
        IdentityHelper.RedirectToReturnUrl(Request.QueryString("ReturnUrl"), 
        Response)
      Else
        ErrorMessage.Text = result.Errors.FirstOrDefault()
      End If
      'Response.Redirect("~/About")
    End If

  End Sub

  Protected Sub CaptchaValidator_ServerValidate(source As Object, args As 
  ServerValidateEventArgs)
    ' validate the Captcha to check we're not dealing with a bot
    args.IsValid = RegisterCaptcha.Validate(args.Value.Trim().ToUpper())

    CaptchaCode.Text = Nothing ' clear previous user input
  End Sub
End Class

In the Page_Load event handler, we set the UserInputID property of the SimpleCaptcha control required for client-side SimpleCaptcha object initialization. This is needed because the custom client-side Ajax SimpleCaptcha validation code will require that object instance to work.

In the CaptchaValidator_ServerValidate function registered to handle server-side validation of the <asp:CustomValidator>, we use the SimpleCaptcha control's Validate() method to check user input. We also clear the Captcha code textbox after validation, since each Captcha code can only be validated once for security reasons.

Scripts\WebForms\WebUICaptchaValidation.js

// CAPTCHA client-side validation function
function ValidateCaptcha(source, arguments) {
  // using the BotDetect.getInstanceByStyleName("yourCaptchaStyleName") to get BotDetect client-side object.
  var captcha= BotDetect.getInstanceByStyleName("RegisterCaptcha");
  var validationUrl = captcha.validationUrl + "&i=" + arguments.Value;
  $.getJSON(validationUrl, function (data) {
    // WebUIValidation.js status update
    source.isvalid = data;
    ValidatorUpdateDisplay(source);
    ValidatorUpdateIsValid();

    // reload the Captcha image if validation failed
    if (!data) { captcha.reloadImage(); }
  });
}

In this file, we extend the unobtrusive client-side WebForms validation with a simple SimpleCaptcha validation function.

To access the client-side SimpleCaptcha object, we read it from the SimpleCaptcha property of the textbox marked with the captchaVal CSS class. We can then get the validationUrl pointing to the BotDetect HttpHandler endpoint used for Ajax SimpleCaptcha validation, append the user input as an additional &i= querystring parameter, and start the Ajax validation call using the jQuery $.getJSON() function.

When the Ajax call returns the JSON-encoded SimpleCaptcha validation result, we forward it to unobtrusive client-side WebForms validation code that updates ASP.NET validator status and display. We also reload the Captcha image immediately if validation failed, since the code it is showing will have been invalidated in that case, and can't be used anymore.

App_Start\BundleConfig.vb

Imports System.Collections.Generic
Imports System.Linq
Imports System.Web
Imports System.Web.Optimization

Public Class BundleConfig
  ' For more information on Bundling, visit http://go.microsoft.
  com/fwlink/?LinkID=303951
  Public Shared Sub RegisterBundles(ByVal bundles As BundleCollection)
    bundles.Add(New ScriptBundle("~/bundles/WebFormsJs").Include(
                    "~/Scripts/WebForms/WebForms.js",
                    "~/Scripts/WebForms/WebUIValidation.js",
                    "~/Scripts/WebForms/WebUICaptchaValidation.js",
                    "~/Scripts/WebForms/MenuStandards.js",
                    "~/Scripts/WebForms/Focus.js",
                    "~/Scripts/WebForms/GridView.js",
                    "~/Scripts/WebForms/DetailsView.js",
                    "~/Scripts/WebForms/TreeView.js",
                    "~/Scripts/WebForms/WebParts.js"))

    ' Order is very important for these files to work, they have explicit 
    dependencies
    bundles.Add(New ScriptBundle("~/bundles/MsAjaxJs").Include(
            "~/Scripts/WebForms/MsAjax/MicrosoftAjax.js",
            "~/Scripts/WebForms/MsAjax/MicrosoftAjaxApplicationServices.js",
            "~/Scripts/WebForms/MsAjax/MicrosoftAjaxTimer.js",
            "~/Scripts/WebForms/MsAjax/MicrosoftAjaxWebForms.js"))

    ' Use the Development version of Modernizr to develop with and learn from. 
    Then, when you’re
    ' ready for production, use the build tool at http://modernizr.com to pick 
    only the tests you need
    bundles.Add(New ScriptBundle("~/bundles/modernizr").Include(
                    "~/Scripts/modernizr-*"))
    ScriptManager.ScriptResourceMapping.AddDefinition("respond", New 
    ScriptResourceDefinition() With {
            .Path = "~/Scripts/respond.min.js",
            .DebugPath = "~/Scripts/respond.js"})

  End Sub
End Class

To make ASP.NET WebForms unobtrusive validation load the SimpleCaptcha Ajax validation function, we have to add it to the /bundles/WebFormsJs script bundle.

Web.config

<?xml version="1.0" encoding="utf-8"?>
<!--
  For more information on how to configure your ASP.NET application, please 
  visit
  http://go.microsoft.com/fwlink/?LinkId=169433
  -->
<configuration>
  <configSections>
  <!-- For more information on Entity Framework configuration, visit http://go.
  microsoft.com/fwlink/?LinkID=237468 -->
  <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.
  EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, 
  PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <connectionStrings>
  <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;
  AttachDbFilename=|DataDirectory|\aspnet-AspNetWebForms451CaptchaExampleVBNet-
  20140226081704.mdf;Initial Catalog=aspnet-AspNetWebForms451CaptchaExampleVBNet-
  20140226081704;Integrated Security=True"
      providerName="System.Data.SqlClient" />
  </connectionStrings>
  <appSettings>
  <!--<add key="owin:AutomaticAppStartup" value="false" />-->
  </appSettings>
  <system.web>

  <authentication mode="None" />
  <compilation debug="false" strict="false" explicit="true" targetFramework="4.5.
  1" />
  <httpRuntime targetFramework="4.5.1" />
  <pages>
    <namespaces>
    <add namespace="System.Web.Optimization" />
    </namespaces>
    <controls>
    <add assembly="Microsoft.AspNet.Web.Optimization.WebForms" 
    namespace="Microsoft.AspNet.Web.Optimization.WebForms" tagPrefix="webopt" />
    <!-- Register the BotDetect tag prefix for easier use in all pages -->
    <add assembly="BotDetect" namespace="BotDetect.Web.UI" 
    tagPrefix="BotDetect"/>
    </controls>
  </pages>
  <membership>
    <providers>
    <!--
        ASP.NET Membership is disabled in this template. Please visit the 
        following link http://go.microsoft.com/fwlink/?LinkId=301889 to learn 
        about the ASP.NET Membership support in this template
        -->
    <clear />
    </providers>
  </membership>
  <profile>
    <providers>
    <!--
        ASP.NET Membership Profile is disabled in this template. Please visit 
        the following link http://go.microsoft.com/fwlink/?LinkId=301889 to 
        learn about the ASP.NET Membership support in this template
        -->
    <clear />
    </providers>
  </profile>
  <roleManager>
    <!--
          ASP.NET Membership Role is disabled in this template. Please visit the 
          following link http://go.microsoft.com/fwlink/?LinkId=301889 to learn 
          about the ASP.NET Membership support in this template
        -->
    <providers>
    <clear />
    </providers>
  </roleManager>
  <!--
            If you are deploying to a cloud environment that has multiple web 
            server instances,
            you should change session state mode from "InProc" to "Custom". In 
            addition,
            change the connection string named "DefaultConnection" to connect to 
            an instance
            of SQL Server (including SQL Azure and SQL  Compact) instead of to 
            SQL Server Express.
      -->
  <httpHandlers>
    <!-- Register the HttpHandler used for BotDetect Simple API requests -->
    <add verb="GET" path="BotDetectCaptcha.ashx" 
    type="BotDetect.Web.SimpleCaptchaHandler, BotDetect"/>
  </httpHandlers>
  


    <providers>
    <add name="DefaultSessionProvider" type="System.Web.Providers.
    DefaultSessionStateProvider, System.Web.Providers, Version=1.0.0.0, 
    Culture=neutral, PublicKeyToken=31bf3856ad364e35" 
    connectionStringName="DefaultConnection" />
    </providers>
  </sessionState>
  </system.web>
  <system.webServer>
  <validation validateIntegratedModeConfiguration="false"/>
  <handlers>
    <!-- Register the HttpHandler used for BotDetect Simple API requests (IIS 7.0+) -->
    <remove name="BotDetectCaptchaHandler"/>
    <add name="BotDetectCaptchaHandler" preCondition="integratedMode" verb="GET" 
    path="BotDetectCaptcha.ashx" type="BotDetect.Web.SimpleCaptchaHandler, BotDetect"/>
  </handlers>
  <modules>
    <remove name="FormsAuthenticationModule" />
  </modules>
  </system.webServer>
  <runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <dependentAssembly>
    <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35"/>
    <bindingRedirect oldVersion="1.0.0.0-1.0.0.0" newVersion="1.0.0.0"/>
    </dependentAssembly>
    <dependentAssembly>
    <assemblyIdentity name="EntityFramework" culture="neutral" 
    publicKeyToken="b77a5c561934e089" />
    <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
    </dependentAssembly>
  </assemblyBinding>
  </runtime>
  <entityFramework>
  <defaultConnectionFactory 
  type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
    <parameters>
    <parameter value="v11.0" />
    </parameters>
  </defaultConnectionFactory>
  <providers>
    <provider invariantName="System.Data.SqlClient" 
    type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
  </providers>
  </entityFramework>
 </configuration>

To allow the application to use BotDetect Captcha protection, we must register the BotDetect HttpHandler in both <system.web><httpHandlers> and <system.webServer><handlers> configuration sections.

botdetect.xml

<?xml version="1.0" encoding="UTF-8"?>
<botdetect xmlns="https://captcha.com/schema/net" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="https://captcha.com/schema/net 
      https://captcha.com/schema/net/botdetect-4.4.0.xsd">

  <captchaStyles>
    <captchaStyle>
      <name>RegisterCaptcha</name>
      <userInputID>CaptchaCode</userInputID>
      <codeLength>3-5</codeLength>
    </captchaStyle>
  </captchaStyles>

</botdetect>

In botdetect.xml, we configure captcha options for the RegisterCaptcha captcha style name. You can find a full list of available Captcha configuration options and related instructions at the Captcha configuration options page .

Visual Studio 2012 / .NET 4.5

The Visual Studio 2012 WebForms application template Captcha Simple API example project shows how to add BotDetect CAPTCHA protection to the registration form included in the default ASP.NET Web Forms Application project template coming with Visual Studio 2012 (File > New Project > Installed > Templates > Visual Basic > Web > ASP.NET Web Forms Application).

Since the Register form uses a CreateUserWizard, the example shows how to include BotDetect CAPTCHA validation in new user data validation (see Account/Register.aspx and Account/Register.aspx.vb source code).

The example also shows how to complement server-side CAPTCHA validation with client-side Ajax CAPTCHA validation using ASP.NET unobtrusive validation applied to all form fields (Scripts/WebForms/WebUICaptchaValidation.js).

Installed Location

By default, the VB.NET version of the ASP.NET WebForms Application Template Captcha Simple API example project is installed at:
C:\Program Files\Captcha Inc\BotDetect 4 CAPTCHA Component\Asp.Net\.NET\WebApp\SimpleAPI\WebFormsVS2012ApplicationTemplateCaptchaExample\VBNet

You can also run it from the BotDetect Start Menu:
Programs > Captcha Inc > BotDetect 4 CAPTCHA Component > ASP.NET > ASP.NET Examples > Run .NET Examples

Example Code Files

Account\Register.aspx

<%@ Page Title="Register" Language="VB" MasterPageFile="~/Site.Master" 
AutoEventWireup="true" CodeBehind="Register.aspx.vb" 
Inherits="AspNetWebForms45CaptchaExampleVBNet.Register" %>

<asp:Content runat="server" ID="BodyContent" ContentPlaceHolderID="MainContent">
  <hgroup class="title">
    <h1><%: Title %>.</h1>
    <h2>Use the form below to create a new account.</h2>
  </hgroup>

  <div class="register">

    <asp:CreateUserWizard runat="server" ID="RegisterUser" 
    ViewStateMode="Disabled" OnCreatedUser="RegisterUser_CreatedUser">
      <LayoutTemplate>
        <asp:PlaceHolder runat="server" ID="wizardStepPlaceholder" />
        <asp:PlaceHolder runat="server" ID="navigationPlaceholder" />
      </LayoutTemplate>
      <WizardSteps>
        <asp:CreateUserWizardStep runat="server" ID="RegisterUserWizardStep">
          <ContentTemplate>
            <p class="message-info">
              Passwords are required to be a minimum of <%: Membership.
              MinRequiredPasswordLength %> characters in length.
            </p>

            <p class="validation-summary-errors">
              <asp:Literal runat="server" ID="ErrorMessage" />
            </p>

            <fieldset>
              <legend>Registration Form</legend>
              <ol>
                <li>
                  <asp:Label runat="server" AssociatedControlID="UserName">User 
                  name</asp:Label>
                  <asp:TextBox runat="server" ID="UserName" />
                  <asp:RequiredFieldValidator runat="server" 
                  ControlToValidate="UserName"
                    CssClass="field-validation-error" Display="Dynamic" 
                    ErrorMessage="The user name field is required." />
                </li>
                <li>
                  <asp:Label runat="server" AssociatedControlID="Email">Email 
                  address</asp:Label>
                  <asp:TextBox runat="server" ID="Email" TextMode="Email" />
                  <asp:RequiredFieldValidator runat="server" 
                  ControlToValidate="Email"
                    CssClass="field-validation-error" Display="Dynamic" 
                    ErrorMessage="The email address field is required." />
                </li>
                <li>
                  <asp:Label runat="server" AssociatedControlID="Password">
                  Password</asp:Label>
                  <asp:TextBox runat="server" ID="Password" TextMode="Password" 
                  />
                  <asp:RequiredFieldValidator runat="server" 
                  ControlToValidate="Password"
                    CssClass="field-validation-error" Display="Dynamic" 
                    ErrorMessage="The password field is required." />
                </li>
                <li>
                  <asp:Label runat="server" 
                  AssociatedControlID="ConfirmPassword">Confirm password</asp:
                  Label>
                  <asp:TextBox runat="server" ID="ConfirmPassword" 
                  TextMode="Password" />
                  <asp:RequiredFieldValidator runat="server" 
                  ControlToValidate="ConfirmPassword"
                    CssClass="field-validation-error" Display="Dynamic" 
                    ErrorMessage="The confirm password field is required." />
                  <asp:CompareValidator runat="server" 
                  ControlToCompare="Password" 
                  ControlToValidate="ConfirmPassword"
                    CssClass="field-validation-error" Display="Dynamic" 
                    ErrorMessage="The password and confirmation password do not 
                    match." />
                </li>
                <!-- Add the controls for CAPTCHA validation to the registration 
                form -->
                <li>
                  <BotDetect:WebFormsSimpleCaptcha ID="RegisterCaptcha" runat="server"/>
                  <asp:Label ID="CaptchaLabel" runat="server" 
                  AssociatedControlID="CaptchaCode">Retype code</asp:Label>
                  <asp:TextBox runat="server" ID="CaptchaCode" 
                  CssClass="captchaVal" />
                  <asp:RequiredFieldValidator ID="RequiredFieldValidator1" 
                  runat="server" ControlToValidate="CaptchaCode"
                    CssClass="field-validation-error" Display="Dynamic" 
                    ErrorMessage="Retyping the code from the picture is required.
                    " />
                  <asp:CustomValidator runat="server" ID="CaptchaValidator" 
                  ControlToValidate="CaptchaCode"
                    CssClass="field-validation-error" Display="Dynamic" 
                    ErrorMessage="Incorrect code, please try again."
                    OnServerValidate="CaptchaValidator_ServerValidate" 
                    ClientValidationFunction="ValidateCaptcha" />
                </li>
              </ol>
              <asp:Button runat="server" CommandName="MoveNext" Text="Register" 
              />
            </fieldset>
          </ContentTemplate>
          <CustomNavigationTemplate />
        </asp:CreateUserWizardStep>
      </WizardSteps>
    </asp:CreateUserWizard>
  </div>
</asp:Content>

To show a SimpleCaptcha test on the registration form, we add a <BotDetect:SimpleCaptcha> control and a textbox in which the visitor will type the displayed Captcha code. We also tag this textbox with a special CSS class (captchaVal), so we can attach client-side jQuery validation to it dynamically without knowing its exact ID.

To make the Captcha code a required form field, we add a <asp:RequiredFieldValidator>. For proper SimpleCaptcha validation comparing the user input to the Captcha code stored on the server during image generation, we add a <asp:CustomValidator> associated with the textbox and set its OnServerValidate property to point to a validation function in form code-behind. To allow unobtrusive Ajax SimpleCaptcha validation, we set its ClientValidationFunction to point at the custom Ajax SimpleCaptcha validation script we will define in client-side code.

Account\Register.aspx.vb

Imports Microsoft.AspNet.Membership.OpenAuth

Imports BotDetect
Imports BotDetect.Web
Imports BotDetect.Web.UI

Public Class Register
  Inherits Page

  Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
    RegisterUser.ContinueDestinationPageUrl = Request.QueryString("ReturnUrl")

    ' get control references; have to use FindControl() calls since controls are 
    inside the CreateUserWizard template
    Dim RegisterCaptcha As WebFormsSimpleCaptcha = 
    TryCast(RegisterUser.CreateUserStep.ContentTemplateContainer.FindControl("RegisterCaptcha"), WebFormsSimpleCaptcha)
    Dim CaptchaCodeTextBox As TextBox = 
    TryCast(RegisterUser.CreateUserStep.ContentTemplateContainer.FindControl("CaptchaCode"), TextBox)



  End Sub

  ' before sending user data to the Membership provider to create a new account,
  ' we first check the CAPTCHA input to ensure bots can't access the Membership
  ' provider at all
  Protected Sub CaptchaValidator_ServerValidate(ByVal source As Object, ByVal 
  args As ServerValidateEventArgs)
    ' get control references; have to use FindControl() calls since controls are 
    inside the CreateUserWizard template
    Dim RegisterCaptcha As WebFormsSimpleCaptcha = 
    TryCast(RegisterUser.CreateUserStep.ContentTemplateContainer.FindControl("RegisterCaptcha"), WebFormsSimpleCaptcha)
    Dim CaptchaCodeTextBox As TextBox = 
    TryCast(RegisterUser.CreateUserStep.ContentTemplateContainer.FindControl("CaptchaCode"), TextBox)

    ' validate the Captcha to check we're not dealing with a bot
    args.IsValid = RegisterCaptcha.Validate(args.Value.Trim().ToUpper())

    CaptchaCodeTextBox.Text = Nothing ' clear previous user input
  End Sub

  Protected Sub RegisterUser_CreatedUser(ByVal sender As Object, 
  ByVal e As EventArgs) Handles RegisterUser.CreatedUser
    FormsAuthentication.SetAuthCookie(RegisterUser.UserName, 
    createPersistentCookie:=False)

    Dim continueUrl As String = RegisterUser.ContinueDestinationPageUrl
    If Not OpenAuth.IsLocalUrl(continueUrl) Then
      continueUrl = "~/"
    End If

    Response.Redirect(continueUrl)
  End Sub
End Class

To access the RegisterCaptcha and CaptchaCode controls in registration form code-behind, we can't use their IDs directly because they are within a ContentTemplate. Instead, we have to use RegisterUser.CreateUserStep.ContentTemplateContainer.FindControl() calls.

In the Page_Load event handler, we set the UserInputID property of the SimpleCaptcha control required for client-side SimpleCaptcha object initialization. This is needed because the custom client-side Ajax SimpleCaptcha validation code will require that object instance to work.

In the CaptchaValidator_ServerValidate function registered to handle server-side validation of the <asp:CustomValidator>, we use the SimpleCaptcha control's Validate() method to check user input. We also clear the Captcha code textbox after validation, since each Captcha code can only be validated once for security reasons.

Scripts\WebForms\WebUICaptchaValidation.js

// CAPTCHA client-side validation function
function ValidateCaptcha(source, arguments) {
  // using the BotDetect.getInstanceByStyleName("yourCaptchaStyleName") to get BotDetect client-side object.
  var captcha= BotDetect.getInstanceByStyleName("RegisterCaptcha");
  var validationUrl = captcha.validationUrl + "&i=" + arguments.Value;
  $.getJSON(validationUrl, function (data) {
    // WebUIValidation.js status update
    source.isvalid = data;
    ValidatorUpdateDisplay(source);
    ValidatorUpdateIsValid();

    // reload the Captcha image if validation failed
    if (!data) { captcha.reloadImage(); }
  });
}

In this file, we extend the unobtrusive client-side WebForms validation with a simple SimpleCaptcha validation function.

To access the client-side SimpleCaptcha object, we read it from the SimpleCaptcha property of the textbox marked with the captchaVal CSS class. We can then get the validationUrl pointing to the BotDetect HttpHandler endpoint used for Ajax SimpleCaptcha validation, append the user input as an additional &i= querystring parameter, and start the Ajax validation call using the jQuery $.getJSON() function.

When the Ajax call returns the JSON-encoded SimpleCaptcha validation result, we forward it to unobtrusive client-side WebForms validation code that updates ASP.NET validator status and display. We also reload the Captcha image immediately if validation failed, since the code it is showing will have been invalidated in that case, and can't be used anymore.

App_Start\BundleConfig.vb

Imports System.Collections.Generic
Imports System.Linq
Imports System.Web
Imports System.Web.Optimization

Public Class BundleConfig
  ' For more information on Bundling, visit http://go.microsoft.
  com/fwlink/?LinkId=254726
  Public Shared Sub RegisterBundles(ByVal bundles As BundleCollection)
    bundles.Add(New ScriptBundle("~/bundles/WebFormsJs").Include(
                    "~/Scripts/WebForms/WebForms.js",
                    "~/Scripts/WebForms/WebUIValidation.js",
                    "~/Scripts/WebForms/WebUICaptchaValidation.js",
                    "~/Scripts/WebForms/MenuStandards.js",
                    "~/Scripts/WebForms/Focus.js",
                    "~/Scripts/WebForms/GridView.js",
                    "~/Scripts/WebForms/DetailsView.js",
                    "~/Scripts/WebForms/TreeView.js",
                    "~/Scripts/WebForms/WebParts.js"))

    ' Order is very important for these files to work, they have explicit 
    dependencies
    bundles.Add(New ScriptBundle("~/bundles/MsAjaxJs").Include(
            "~/Scripts/WebForms/MsAjax/MicrosoftAjax.js",
            "~/Scripts/WebForms/MsAjax/MicrosoftAjaxApplicationServices.js",
            "~/Scripts/WebForms/MsAjax/MicrosoftAjaxTimer.js",
            "~/Scripts/WebForms/MsAjax/MicrosoftAjaxWebForms.js"))

    ' Use the Development version of Modernizr to develop with and learn from. 
    Then, when you’re
    ' ready for production, use the build tool at http://modernizr.com to pick 
    only the tests you need
    bundles.Add(New ScriptBundle("~/bundles/modernizr").Include(
                    "~/Scripts/modernizr-*"))

  End Sub
End Class

To make ASP.NET WebForms unobtrusive validation load the SimpleCaptcha Ajax validation function, we have to add it to the /bundles/WebFormsJs script bundle.

Web.config

<?xml version="1.0" encoding="utf-8"?>
<!--
  For more information on how to configure your ASP.NET application, please 
  visit
  http://go.microsoft.com/fwlink/?LinkId=169433
  -->
<configuration>
  <system.web>
    <compilation debug="false" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" />
    <httpHandlers>
      <!-- Register the HttpHandler used for BotDetect Simple API requests -->
      <add verb="GET" path="BotDetectCaptcha.ashx" 
      type="BotDetect.Web.SimpleCaptchaHandler, BotDetect" />
    </httpHandlers>
    <pages>
      <namespaces>
        <add namespace="System.Web.Optimization" />
        <add namespace="BotDetect" />
        <add namespace="BotDetect.Web" />
        <add namespace="BotDetect.Web.UI" />
      </namespaces>
      <controls>
        <add assembly="Microsoft.AspNet.Web.Optimization.WebForms" 
        namespace="Microsoft.AspNet.Web.Optimization.WebForms" 
        tagPrefix="webopt" />
        <!-- Register the BotDetect tag prefix for easier use in all pages -->
        <add assembly="BotDetect" namespace="BotDetect.Web.UI" 
        tagPrefix="BotDetect" />
      </controls>
    </pages>
    <authentication mode="Forms">
      <forms loginUrl="~/Account/Login.aspx" timeout="2880" />
    </authentication>
    <profile defaultProvider="DefaultProfileProvider">
      <providers>
        <add name="DefaultProfileProvider" type="System.Web.Providers.
        DefaultProfileProvider, System.Web.Providers, Version=1.0.0.0, 
        Culture=neutral, PublicKeyToken=31bf3856ad364e35" 
        connectionStringName="DefaultConnection" applicationName="/" />
      </providers>
    </profile>
    <membership defaultProvider="MockMembershipProvider">
      <providers>
        <add name="MockMembershipProvider" applicationName="/" 
        type="AspNetWebForms45CaptchaExampleVBNet.MockMembershipProvider" />
      </providers>
    </membership>
    <roleManager defaultProvider="DefaultRoleProvider">
      <providers>
        <add name="DefaultRoleProvider" type="System.Web.Providers.
        DefaultRoleProvider, System.Web.Providers, Version=1.0.0.0, 
        Culture=neutral, PublicKeyToken=31bf3856ad364e35" 
        connectionStringName="DefaultConnection" applicationName="/" />
      </providers>
    </roleManager>
    

    cookieless="AutoDetect" timeout="20" 

      <providers>
        <add name="DefaultSessionProvider" type="System.Web.Providers.
        DefaultSessionStateProvider, System.Web.Providers, Version=1.0.0.0, 
        Culture=neutral, PublicKeyToken=31bf3856ad364e35" 
        connectionStringName="DefaultConnection" />
      </providers>
    </sessionState>
  </system.web>
  <system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <handlers>
      <!-- Register the HttpHandler used for BotDetect Simple API requests (IIS 7.0+) -->
      <remove name="BotDetectCaptchaHandler" />
      <add name="BotDetectCaptchaHandler" preCondition="integratedMode" 
      verb="GET" path="BotDetectCaptcha.ashx" 
      type="BotDetect.Web.SimpleCaptchaHandler, BotDetect" />
    </handlers>
  </system.webServer>
 </configuration>

To allow the application to use BotDetect Captcha protection, we must register the BotDetect HttpHandler in both <system.web><httpHandlers> and <system.webServer><handlers> configuration sections.

botdetect.xml

<?xml version="1.0" encoding="UTF-8"?>
<botdetect xmlns="https://captcha.com/schema/net" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="https://captcha.com/schema/net 
      https://captcha.com/schema/net/botdetect-4.4.0.xsd">

  <captchaStyles>
    <captchaStyle>
      <name>RegisterCaptcha</name>
      <userInputID>CaptchaCode</userInputID>
      <codeLength>3-5</codeLength>
    </captchaStyle>
  </captchaStyles>

</botdetect>

In botdetect.xml, we configure captcha options for the RegisterCaptcha captcha style name. You can find a full list of available Captcha configuration options and related instructions at the Captcha configuration options page .