BotDetect ASP.NET 2.0 Ajax CAPTCHA VB.NET Code Sample
The BotDetect ASP.NET CAPTCHA Ajax code sample shows how to make the BotDetect CAPTCHA validation work inside an ASP.NET 2.0 Ajax UpdatePanel. It can be used when migrating BotDetect-protected forms to ASP.NET Ajax.
The Captcha control code is the same whether you are using .NET Framework 2.0 + the ASP.NET Ajax Extensions 1.0 or the .NET Framework 3.5 (where the Ajax extensions code has been integrated with the core framework). The only difference between the ASP.NET Ajax versions is in the web.config files, so there are two separate versions of this sample included in the BotDetect installation.
Sample Project Location
By default, this sample project is installed at
C:\Program Files\Lanapsoft\BotDetect\ASP.NET 2.0\v2.0\Samples\VBNetBotDetectAspNet20AjaxDemo\ and VBNetBotDetectAspNet35AjaxDemo.
You can also run it from the Start Menu:
Programs > Lanapsoft > BotDetect > ASP.NET 2.0 > v2.0 > Samples > VB.Net BotDetect ASP.NET Ajax CAPTCHA Sample (.NET 2.0) and VB.Net BotDetect ASP.NET Ajax CAPTCHA Sample (.NET 3.5).
Default.aspx
Full Source Code Listing
<%@ Page Language="VB" AutoEventWireup="true"
CodeFile="Default.aspx.vb" Inherits="_Default" %>
<%@ Register Assembly="Lanap.BotDetect" Namespace="Lanap.BotDetect"
TagPrefix="BotDetect" %>
<!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 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>
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<asp:UpdatePanel ID="CaptchaUpdatePanel" runat="server"
UpdateMode="Conditional">
<ContentTemplate>
<div>
<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>
<div id="ValidationDiv">
<asp:TextBox id="CodeTextBox" runat="server">
</asp:TextBox>
<asp:Button id="ValidateButton" runat="server">
</asp:Button>
<asp:Label id="MessageCorrectLabel"
runat="server"></asp:Label>
<asp:Label id="MessageIncorrectLabel"
runat="server"></asp:Label>
</div>
</ContentTemplate>
</asp:UpdatePanel>
</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 and make it validate using Ajax partial postbacks are bold. 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 <asp:ScriptManager> control is needed to enable ASP.NET Ajax functionality, and the whole CAPTCHA validation part of the page has been placed inside an <asp:UpdatePanel> with the UpdateMode="Conditional" setting, allowing partial postbacks and redrawing only of the part of the form contained within the UpdatePanel <ContentTemplate>.
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
// clear user input on Reload button clicks
string scriptTemplate = @"
function LBD_ClearUserInput() {{
var LBD_textBox = document.getElementById('{0}');
if(LBD_textBox) {{
LBD_textBox.value = '';
}}
}}
LBD_RegisterHandler('PreReloadCaptchaImage',
LBD_ClearUserInput);
";
string script = String.Format(scriptTemplate,
CodeTextBox.ClientID);
if (!Page.ClientScript.IsStartupScriptRegistered(
"CaptchaReloadClearInput"))
{
Page.ClientScript.RegisterStartupScript(this.GetType(),
"CaptchaReloadClearInput", script, true);
}
// automatically lowercase user input
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
There is no extra code required for Ajax validation in the form codebehind, since the UpdatePanel partial postback is processed the same as a full postback (regarding the ASP.NET page life-cycle), except that changes to controls outside the <ContentTemplate> are effectively discarded.
Web.config (.NET 2.0)
Full Source Code Listing
<?xml version="1.0"?>
<configuration>
<configSections>
<sectionGroup name="system.web.extensions"
type="System.Web.Configuration.SystemWebExtensionsSectionGroup,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35">
<sectionGroup name="scripting"
type="System.Web.Configuration.ScriptingSectionGroup,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35">
<section name="scriptResourceHandler" type="System.Web.
Configuration.ScriptingScriptResourceHandlerSection,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" requirePermission="false"
allowDefinition="MachineToApplication"/>
<sectionGroup name="webServices" type="System.Web.
Configuration.ScriptingWebServicesSectionGroup,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35">
<section name="jsonSerialization" type="System.Web.
Configuration.ScriptingJsonSerializationSection,
System.Web.Extensions, Version=1.0.61025.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35"
requirePermission="false" allowDefinition="Everywhere"/>
<section name="profileService" type="System.Web.
Configuration.ScriptingProfileServiceSection,
System.Web.Extensions, Version=1.0.61025.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35"
requirePermission="false"
allowDefinition="MachineToApplication"/>
<section name="authenticationService" type="System.Web.
Configuration.ScriptingAuthenticationServiceSection,
System.Web.Extensions, Version=1.0.61025.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35"
requirePermission="false"
allowDefinition="MachineToApplication"/>
</sectionGroup>
</sectionGroup>
</sectionGroup>
</configSections>
<system.web>
<pages>
<controls>
<add tagPrefix="asp" namespace="System.Web.UI"
assembly="System.Web.Extensions, Version=1.0.61025.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</controls>
</pages>
<!--
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.Web.Extensions, Version=1.0.61025.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add assembly="System.Design, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
</assemblies>
</compilation>
<httpHandlers>
<remove verb="*" path="*.asmx"/>
<add verb="*" path="LanapCaptcha.aspx"
type="Lanap.BotDetect.CaptchaHandler, Lanap.BotDetect"/>
<add verb="*" path="*.asmx" validate="false"
type="System.Web.Script.Services.ScriptHandlerFactory,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35"/>
<add verb="*" path="*_AppService.axd" validate="false"
type="System.Web.Script.Services.ScriptHandlerFactory,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35"/>
<add verb="GET,HEAD" path="ScriptResource.axd"
type="System.Web.Handlers.ScriptResourceHandler,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" validate="false"/>
</httpHandlers>
<httpModules>
<add name="ScriptModule" type="System.Web.Handlers.ScriptModule,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35"/>
</httpModules>
<sessionState mode="InProc" cookieless="AutoDetect" timeout="20"
sessionIDManagerType="Lanap.BotDetect.Persistence.
CustomSessionIDManager, Lanap.BotDetect" />
<customErrors mode="On" defaultRedirect="~/Error.html" />
</system.web>
<system.web.extensions>
<scripting>
<webServices>
<!-- Uncomment this line to customize maxJsonLength and add a
custom converter -->
<!--
<jsonSerialization maxJsonLength="500">
<converters>
<add name="ConvertMe"
type="Acme.SubAcme.ConvertMeTypeConverter"/>
</converters>
</jsonSerialization>
-->
<!-- Uncomment this line to enable the authentication service.
Include requireSSL="true" if appropriate. -->
<!--
<authenticationService enabled="true"
requireSSL = "true|false"/>
-->
<!-- Uncomment these lines to enable the profile service.
To allow profile properties to be retrieved and modified
in ASP.NET AJAX applications, you need to add each property
name to the readAccessProperties and writeAccessProperties
attributes. -->
<!--
<profileService enabled="true"
readAccessProperties="propertyname1,propertyname2"
writeAccessProperties="propertyname1,propertyname2" />
-->
</webServices>
<!--
<scriptResourceHandler enableCompression="true"
enableCaching="true" />
-->
</scripting>
</system.web.extensions>
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules>
<add name="ScriptModule" preCondition="integratedMode"
type="System.Web.Handlers.ScriptModule, System.Web.Extensions,
Version=1.0.61025.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35"/>
</modules>
<handlers>
<remove name="WebServiceHandlerFactory-Integrated"/>
<add name="ScriptHandlerFactory" verb="*" path="*.asmx"
preCondition="integratedMode"
type="System.Web.Script.Services.ScriptHandlerFactory,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35"/>
<add name="ScriptHandlerFactoryAppServices" verb="*"
path="*_AppService.axd" preCondition="integratedMode"
type="System.Web.Script.Services.ScriptHandlerFactory,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35"/>
<add name="ScriptResource" preCondition="integratedMode"
verb="GET,HEAD" path="ScriptResource.axd"
type="System.Web.Handlers.ScriptResourceHandler,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35"/>
<remove name="LanapCaptchaHandler" />
<add name="LanapCaptchaHandler" preCondition="integratedMode"
verb="*" path="LanapCaptcha.aspx"
type="Lanap.BotDetect.CaptchaHandler, Lanap.BotDetect" />
</handlers>
</system.webServer>
</configuration>
Explanation
This version of the Web.config file is the one you will use with .NET Framework 2.0 + ASP.NET Ajax Extensions 1.0. Lines necessary for BotDetect CAPTCHA to function properly have been bold, other lines are all standard values generated by Visual Studio 2005 with ASP.NET Ajax Extensions 1.0 installed.
Web.config (.NET 3.5)
Full Source Code Listing
<?xml version="1.0"?>
<configuration>
<configSections>
<sectionGroup name="system.web.extensions"
type="System.Web.Configuration.SystemWebExtensionsSectionGroup,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35">
<sectionGroup name="scripting" type="System.Web.
Configuration.ScriptingSectionGroup, System.Web.Extensions,
Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35">
<section name="scriptResourceHandler" type="System.Web.
Configuration.ScriptingScriptResourceHandlerSection,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35" requirePermission="false"
allowDefinition="MachineToApplication"/>
<sectionGroup name="webServices" type="System.Web.
Configuration.ScriptingWebServicesSectionGroup,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35">
<section name="jsonSerialization" type="System.Web.
Configuration.ScriptingJsonSerializationSection,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35" requirePermission="false"
allowDefinition="Everywhere"/>
<section name="profileService" type="System.Web.
Configuration.ScriptingProfileServiceSection,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35" requirePermission="false"
allowDefinition="MachineToApplication"/>
<section name="authenticationService" type="System.Web.
Configuration.ScriptingAuthenticationServiceSection,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35" requirePermission="false"
allowDefinition="MachineToApplication"/>
<section name="roleService" type="System.Web.Configuration.
ScriptingRoleServiceSection, System.Web.Extensions,
Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35" requirePermission="false"
allowDefinition="MachineToApplication"/>
</sectionGroup>
</sectionGroup>
</sectionGroup>
</configSections>
<system.web>
<pages>
<controls>
<add tagPrefix="asp" namespace="System.Web.UI"
assembly="System.Web.Extensions, Version=3.5.0.0,
Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add tagPrefix="asp" namespace="System.Web.UI.WebControls"
assembly="System.Web.Extensions, Version=3.5.0.0,
Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</controls>
</pages>
<!--
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="true">
<assemblies>
<add assembly="System.Design, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
<add assembly="System.Core, Version=3.5.0.0,
Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Web.Extensions, Version=3.5.0.0,
Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Xml.Linq, Version=3.5.0.0,
Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Data.DataSetExtensions,
Version=3.5.0.0, Culture=neutral,
PublicKeyToken=B77A5C561934E089"/>
</assemblies>
</compilation>
<httpHandlers>
<remove verb="*" path="*.asmx"/>
<add verb="*" path="LanapCaptcha.aspx"
type="Lanap.BotDetect.CaptchaHandler, Lanap.BotDetect"/>
<add verb="*" path="*.asmx" validate="false"
type="System.Web.Script.Services.ScriptHandlerFactory,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35"/>
<add verb="*" path="*_AppService.axd" validate="false"
type="System.Web.Script.Services.ScriptHandlerFactory,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35"/>
<add verb="GET,HEAD" path="ScriptResource.axd"
type="System.Web.Handlers.ScriptResourceHandler,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35" validate="false"/>
</httpHandlers>
<httpModules>
<add name="ScriptModule" type="System.Web.Handlers.ScriptModule,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35"/>
</httpModules>
<sessionState mode="InProc" cookieless="AutoDetect"
timeout="20" sessionIDManagerType="
Lanap.BotDetect.Persistence.CustomSessionIDManager,
Lanap.BotDetect"/>
<customErrors mode="On" defaultRedirect="~/Error.html"/>
</system.web>
<system.web.extensions>
<scripting>
<webServices>
<!-- Uncomment this line to customize maxJsonLength and add a
custom converter -->
<!--
<jsonSerialization maxJsonLength="500">
<converters>
<add name="ConvertMe"
type="Acme.SubAcme.ConvertMeTypeConverter"/>
</converters>
</jsonSerialization>
-->
<!-- Uncomment this line to enable the authentication service.
Include requireSSL="true" if appropriate. -->
<!--
<authenticationService enabled="true"
requireSSL = "true|false"/>
-->
<!-- Uncomment these lines to enable the profile service.
To allow profile properties to be retrieved and modified
in ASP.NET AJAX applications, you need to add each property
name to the readAccessProperties and writeAccessProperties
attributes. -->
<!--
<profileService enabled="true"
readAccessProperties="propertyname1,propertyname2"
writeAccessProperties="propertyname1,propertyname2" />
-->
</webServices>
<!--
<scriptResourceHandler enableCompression="true"
enableCaching="true" />
-->
</scripting>
</system.web.extensions>
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules>
<remove name="ScriptModule"/><add name="ScriptModule"
preCondition="managedHandler"
type="System.Web.Handlers.ScriptModule, System.Web.Extensions,
Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35"/>
</modules>
<handlers>
<remove name="ScriptHandlerFactory"/>
<remove name="ScriptHandlerFactoryAppServices"/>
<remove name="ScriptResource"/>
<remove name="WebServiceHandlerFactory-Integrated"/>
<add name="ScriptHandlerFactory" verb="*" path="*.asmx"
preCondition="integratedMode" type="System.Web.Script.
Services.ScriptHandlerFactory, System.Web.Extensions,
Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35"/>
<add name="ScriptHandlerFactoryAppServices" verb="*"
path="*_AppService.axd" preCondition="integratedMode"
type="System.Web.Script.Services.ScriptHandlerFactory,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35"/>
<add name="ScriptResource" preCondition="integratedMode"
verb="GET,HEAD" path="ScriptResource.axd"
type="System.Web.Handlers.ScriptResourceHandler,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35"/>
<remove name="LanapCaptchaHandler" />
<add name="LanapCaptchaHandler"
preCondition="integratedMode" verb="*"
path="LanapCaptcha.aspx"
type="Lanap.BotDetect.CaptchaHandler, Lanap.BotDetect" />
</handlers>
</system.webServer>
<system.codedom>
<compilers>
<compiler language="VB.NET;cs;csharp" extension=".cs"
type="Microsoft.CSharp.CSharpCodeProvider,System,
Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089" warningLevel="4">
<providerOption name="CompilerVersion" value="v3.5"/>
<providerOption name="WarnAsError" value="false"/>
</compiler>
<compiler language="vb;vbs;visualbasic;vbscript"
extension=".vb" type="Microsoft.VisualBasic.VBCodeProvider,
System, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089" warningLevel="4">
<providerOption name="CompilerVersion" value="v3.5"/>
<providerOption name="OptionInfer" value="true"/>
<providerOption name="WarnAsError" value="false"/>
</compiler>
</compilers>
</system.codedom>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Extensions"
publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="1.0.0.0-1.1.0.0"
newVersion="3.5.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Extensions.Design"
publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="1.0.0.0-1.1.0.0"
newVersion="3.5.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
Explanation
This version of the Web.config file is the one you will use with .NET Framework 3.5 and Visual Studio 2008. Lines necessary for BotDetect CAPTCHA to function properly have been bold, other lines are all standard values generated by Visual Studio 2008.
Current BotDetect Versions
- BotDetect ASP.NET CAPTCHA v2.0.152009–11–23
- BotDetect ASP CAPTCHA v2.0.92009–02–12





