ASP.NET CAPTCHA Request Dynamic Settings VB.NET Code Example

The ASP.NET Captcha request dynamic settings example project shows how to dynamically adjust BotDetect CAPTCHA configuration, potentially on each Http request made by the client.

First Time Here?

Check the BotDetect Developer Crash Course for key integration steps.

Any code setting Captcha properties in the Captcha.InitializedWebCaptcha event handler will be executed not only for each protected form GET or POST request (like Captcha configuration code placed in form source would be), but also for each each GET request loading a Captcha image or sound, or making an Ajax Captcha validation call.

If configured values are dynamic (e.g. randomized from a range), they will be re-calculated for each Captcha challenge generated. For example, Captcha ImageStyle randomized in Captcha.InitializedWebCaptcha event handler code will change on each Captcha reload button click.

This means your code can reliably keep track of visitor interaction with the Captcha challenge and dynamically adjust its settings. Also, while Captcha.InitializedWebCaptcha settings apply to all Captcha instances by default, you can also selectively apply them based on CaptchaId.

To show an example of the possible dynamic Captcha configuration adjustments, this code example increases the difficulty of the Captcha test if the visitor associated with the current ASP.NET Session fails a certain number of Captcha validation attempts, and also sets the Captcha locale to Chinese for requests from a certain IP range.

Download the BotDetect ASP.NET CAPTCHA Generator archive to run this example
  • C#
  • VB.NET

Visual Studio 2005-2017 / .NET 2.0 and onwards

Within this page, the root folder of the extracted archive is referred as the <BDC-DIR>.

This example is in the <BDC-DIR>/lgcy-on-lgcy/examples/t_api-captcha~conf_via-dynamic_config/vbnet/ folder; and contains the following files:


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

<!DOCTYPE html> 

<html xmlns=""> 
<head id="Head1" runat="server"> 
  <title>BotDetect ASP.NET CAPTCHA Options: Request Dynamic Settings Code 
  <link type="text/css" rel="Stylesheet" href="StyleSheet.css" /> 
  <form runat="server" class="column" id="form1"> 
    <h1>BotDetect ASP.NET CAPTCHA Options: 
            <br /> 
      Request Dynamic Settings Code Example</h1> 

      <legend>ASP.NET WebForm CAPTCHA Validation</legend> 
      <p class="prompt"> 
        <label for="CaptchaCodeTextBox">Retype the characters from the picture:</label> 
      <BotDetect:WebFormsCaptcha runat="server" ID="DynamicCaptcha" 
      UserInputID="CaptchaCodeTextBox" /> 
      <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" 

    <div id="output"> 
      <asp:Literal runat="server" ID="StatusLiteral" /> 


Imports BotDetect.Web 
Imports BotDetect 
Imports System 
Imports System.Collections.Generic 
Imports System.Linq 
Imports System.Web 
Imports System.Web.UI 
Imports System.Web.UI.WebControls 
Partial Class _Default Inherits System.Web.UI.Page 

  Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) 
  Handles Me.Init 
    AddHandler Captcha.InitializedWebCaptcha, AddressOf 

  End Sub 

  Private Sub DynamicCaptcha_InitializedWebCaptcha(ByVal sender As Object, 
  ByVal e As InitializedWebCaptchaEventArgs) Handles DynamicCaptcha.InitializedWebCaptcha 

    Dim captchaInstance As Captcha 
    captchaInstance = DirectCast(sender, Captcha) 

    ' Captcha.InitializedWebCaptcha event handlers are global and apply to all  
    ' Captcha instances  
    ' in the application if some settings need to be apply only to a particular  
    ' Captcha  
    ' instance, this is how settings can be conditionally applied based on  
    ' CaptchaId 
    If (e.CaptchaId = DynamicCaptcha.CaptchaId) Then 

      captchaInstance.SoundEnabled = False 
    End If 

    ' re-calculated on each image request 
    Dim imageStyles As ImageStyle() = {ImageStyle.Graffiti, ImageStyle.SunAndWarmAir, ImageStyle.Overlap} 
    captchaInstance.ImageStyle = CaptchaRandomization.GetRandomImageStyle(imageStyles) 

    ' dynamic Captcha settings depending on failed validation attempts: increase  
    ' Captcha  
    ' difficulty according to number of previously failed validations 
    Dim count As Integer = DynamicCaptchaExample.ValidationCounter.GetFailedValidationsCount() 
    If (count < 3) Then 

      captchaInstance.CodeLength = CaptchaRandomization.GetRandomCodeLength(3, 4) 
      captchaInstance.CodeStyle = CodeStyle.Numeric 
      captchaInstance.CodeTimeout = 600 ' 10 minutes 

    ElseIf (count < 10) Then 

      captchaInstance.CodeLength = CaptchaRandomization.GetRandomCodeLength(4, 6) 
      captchaInstance.CodeStyle = CodeStyle.Alpha 
      captchaInstance.CodeTimeout = 180 ' 3 minutes 


      captchaInstance.CodeLength = CaptchaRandomization.GetRandomCodeLength(6, 9) 
      captchaInstance.CodeStyle = CodeStyle.Alphanumeric 
      captchaInstance.CodeTimeout = 60 ' 1 minute 
    End If 

    ' set Captcha locale to Chinese for requests from a certain IP range 
    Dim ipRange As String = "223.254." 
    Dim requestFromRangeDetected As Boolean = False 

    ' have to use HttpContext.Current.Request and not Page.Request because Page 
    ' properties won't be set for Captcha image and sound requests serverd directly 
    ' by the BotDetect Captcha HttpHandler 
    If (Not (HttpContext.Current.Request Is Nothing) And 
      Not String.IsNullOrEmpty(HttpContext.Current.Request.UserHostAddress) 
      And HttpContext.Current.Request.UserHostAddress.StartsWith(ipRange)) 

      requestFromRangeDetected = True 
    End If 

    If (requestFromRangeDetected) Then 

      captchaInstance.CodeStyle = CodeStyle.Alpha 
      captchaInstance.Locale = "cmn" 
    End If 
  End Sub 

  Protected Sub Page_PreRender(ByVal sender As Object, ByVal e As  _ 
  System.EventArgs) Handles Me.PreRender 
    ' initial page setup 
    If (Not IsPostBack) Then 

      ' 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 
    End If 

    If (IsPostBack) Then 

      ' validate the Captcha to check we're not dealing with a bot 
      Dim isHuman As Boolean = DynamicCaptcha.Validate() 
      If (isHuman) Then 

        CaptchaCorrectLabel.Visible = True 
        CaptchaIncorrectLabel.Visible = False 


        CaptchaCorrectLabel.Visible = False 
        CaptchaIncorrectLabel.Visible = True 
      End If 
    End If 

    ' update status display 
    Dim count As Integer = DynamicCaptchaExample.ValidationCounter.GetFailedValidationsCount() 
    StatusLiteral.Text = String.Format("<p>Failed Captcha validations: {0}</p>", 
    If (count < 3) Then 

      StatusLiteral.Text += "<p>Dynamic Captcha difficulty: Easy</p>" 

    ElseIf (count < 10) Then 

      StatusLiteral.Text += "<p>Dynamic Captcha difficulty: Moderate</p>" 


      StatusLiteral.Text += "<p>Dynamic Captcha difficulty: Hard</p>" 
    End If 
  End Sub 
End Class 


Imports Microsoft.VisualBasic 
Imports System 
Namespace DynamicCaptchaExample 
  ' <summary> 
  ' Summary description for Counter 
  ' </summary> 
  Public Class ValidationCounter 

    Const FailedValidationsCountKey As String = "FailedValidationsCountKey" 

    Public Shared Function GetFailedValidationsCount() As Integer 

      Dim count As Integer = 0 
      Dim saved As Object = HttpContext.Current.Session(FailedValidationsCountKey) 
      If (Not (saved Is Nothing)) Then 


          count = DirectCast(saved, Integer) 

        Catch ex As InvalidCastException 

          ' ignore cast errors 
          count = 0 
        End Try 
      End If 
      Return count 

    End Function 
    Public Shared Sub IncrementFailedValidationsCount() 

      Dim count As Integer = GetFailedValidationsCount() 
      count += 1 
      HttpContext.Current.Session(FailedValidationsCountKey) = count 
    End Sub 

    Public Shared Sub ResetFailedValidationsCount() 

    End Sub 
  End Class 
End Namespace 


<?xml version="1.0"?> 

  For more information on how to configure your ASP.NET application, please  

    <section name="botDetect" requirePermission="false" 
    type="BotDetect.Configuration.BotDetectConfigurationSection, BotDetect"/> 
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/> 
    <add key="ValidationSettings:UnobtrusiveValidationMode" value="None"/> 
      <!-- Register the HttpHandler used for BotDetect Captcha requests --> 
      <add verb="GET" path="BotDetectCaptcha.ashx" 
      type="BotDetect.Web.CaptchaHandler, BotDetect"/> 
    <!-- 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 controlRenderingCompatibilityVersion="4.5" enableSessionState="true"> 
      <!-- Register the BotDetect tag prefix for easier use in all pages --> 
      <add assembly="BotDetect" namespace="BotDetect.Web.UI" 
    <compilation debug="false" targetFramework="4.5"/> 
    <httpRuntime requestValidationMode="4.5" targetFramework="4.5" 
    encoderType="System.Web.Security.AntiXss.AntiXssEncoder, System.Web, Version=, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/> 
    <machineKey compatibilityMode="Framework45"/> 
    <validation validateIntegratedModeConfiguration="false"/> 
      <!-- 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"/> 
  <botDetect helpLinkEnabled="true" helpLinkMode="image" />