ASP.NET MVC 2.0 Application Template CAPTCHA VB.NET Code Example
The ASP.NET MVC 2.0 application template Captcha example project shows how to use the BotDetect CAPTCHA MvcCaptcha
control in ASP.NET MVC 2.0 web applications.
First Time Here?
Check the BotDetect ASP.NET MVC Captcha Quickstart for key integration steps.
Starting with the default ASP.NET MVC 2.0 Visual Studio 2008 project template, the example includes all code required to add CAPTCHA validation to the Account
controller Register
action.
The example remembers when the CAPTCHA is successfully solved within a single registration, and doesn't display it again if there are errors with other form values (the username, for example).
You can get a new CAPTCHA using the Register
action link in the top right corner of the page, and see the explanation in the Account
controller code.
→ ASP.NET MVC version:
- ASP.NET MVC 5.0
- ASP.NET MVC 4.0
- ASP.NET MVC 3.0
- ASP.NET MVC 2.0
- MVC 1.0
→ .NET programming language:
- C#
- VB.NET
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-mvc2-web.security.membership/vbnet/
folder; and contains the following files:
- Models\AccountModels.vb
- Views\Account\Register.aspx
- Views\Shared\Site.Master
- Controllers\AccountController.vb
- Global.asax.vb
- CaptchaHelper.vb
- Web.config
Models\AccountModels.vb
Imports System.ComponentModel Imports System.ComponentModel.DataAnnotations Imports System.Globalization Imports BotDetect.Web.Mvc #Region "Models" <PropertiesMustMatch("NewPassword", "ConfirmPassword", ErrorMessage:="The new password and confirmation password do not match.")> _ Public Class ChangePasswordModel Private oldPasswordValue As String Private newPasswordValue As String Private confirmPasswordValue As String <Required()> _ <DataType(DataType.Password)> _ <DisplayName("Current password")> _ Public Property OldPassword() As String Get Return oldPasswordValue End Get Set(ByVal value As String) oldPasswordValue = value End Set End Property <Required()> _ <ValidatePasswordLength()> _ <DataType(DataType.Password)> _ <DisplayName("New password")> _ Public Property NewPassword() As String Get Return newPasswordValue End Get Set(ByVal value As String) newPasswordValue = value End Set End Property <Required()> _ <DataType(DataType.Password)> _ <DisplayName("Confirm new password")> _ Public Property ConfirmPassword() As String Get Return confirmPasswordValue End Get Set(ByVal value As String) confirmPasswordValue = value End Set End Property End Class Public Class LogOnModel Private userNameValue As String Private passwordValue As String Private rememberMeValue As Boolean <Required()> _ <DisplayName("User name")> _ Public Property UserName() As String Get Return userNameValue End Get Set(ByVal value As String) userNameValue = value End Set End Property <Required()> _ <DataType(DataType.Password)> _ <DisplayName("Password")> _ Public Property Password() As String Get Return passwordValue End Get Set(ByVal value As String) passwordValue = value End Set End Property <DisplayName("Remember me?")> _ Public Property RememberMe() As Boolean Get Return rememberMeValue End Get Set(ByVal value As Boolean) rememberMeValue = value End Set End Property End Class <PropertiesMustMatch("Password", "ConfirmPassword", ErrorMessage:="The password and confirmation password do not match.")> _ Public Class RegisterModel Private userNameValue As String Private passwordValue As String Private confirmPasswordValue As String Private emailValue As String <Required()> _ <DisplayName("User name")> _ Public Property UserName() As String Get Return userNameValue End Get Set(ByVal value As String) userNameValue = value End Set End Property <Required()> _ <DataType(DataType.EmailAddress)> _ <DisplayName("Email address")> _ Public Property Email() As String Get Return emailValue End Get Set(ByVal value As String) emailValue = value End Set End Property <Required()> _ <ValidatePasswordLength()> _ <DataType(DataType.Password)> _ <DisplayName("Password")> _ Public Property Password() As String Get Return passwordValue End Get Set(ByVal value As String) passwordValue = value End Set End Property <Required()> _ <DataType(DataType.Password)> _ <DisplayName("Confirm password")> _ Public Property ConfirmPassword() As String Get Return confirmPasswordValue End Get Set(ByVal value As String) confirmPasswordValue = value End Set End Property ' add Captcha code as a field in the protected action Model Private captchaCodeValue As String <Required(ErrorMessage:="Retyping the characters from the picture is required.")> _ <DisplayName("Please retype the characters from the picture")> _ Public Property CaptchaCode() As String Get Return captchaCodeValue End Get Set(ByVal value As String) captchaCodeValue = value End Set End Property End Class #End Region #Region "Services" ' The FormsAuthentication type is sealed and contains static members, so it is ' difficult to ' unit test code that calls its members. The interface and helper class below ' demonstrate ' how to create an abstract wrapper around such a type in order to make the ' AccountController ' code unit testable. Public Interface IMembershipService ReadOnly Property MinPasswordLength() As Integer Function ValidateUser(ByVal userName As String, ByVal password As String) As Boolean Function CreateUser(ByVal userName As String, ByVal password As String, ByVal email As String) As MembershipCreateStatus Function ChangePassword(ByVal userName As String, ByVal oldPassword As String, ByVal newPassword As String) As Boolean End Interface Public Class AccountMembershipService Implements IMembershipService Private ReadOnly _provider As MembershipProvider Public Sub New() Me.New(Nothing) End Sub Public Sub New(ByVal provider As MembershipProvider) _provider = If(provider, Membership.Provider) End Sub Public ReadOnly Property MinPasswordLength() As Integer Implements IMembershipService.MinPasswordLength Get Return _provider.MinRequiredPasswordLength End Get End Property Public Function ValidateUser(ByVal userName As String, ByVal password As String) As Boolean Implements IMembershipService.ValidateUser If String.IsNullOrEmpty(userName) Then Throw New ArgumentException("Value cannot be null or empty.", "userName") If String.IsNullOrEmpty(password) Then Throw New ArgumentException("Value cannot be null or empty.", "password") Return _provider.ValidateUser(userName, password) End Function Public Function CreateUser(ByVal userName As String, ByVal password As String, ByVal email As String) As MembershipCreateStatus Implements IMembershipService.CreateUser If String.IsNullOrEmpty(userName) Then Throw New ArgumentException("Value cannot be null or empty.", "userName") If String.IsNullOrEmpty(password) Then Throw New ArgumentException("Value cannot be null or empty.", "password") If String.IsNullOrEmpty(email) Then Throw New ArgumentException("Value cannot be null or empty.", "email") Dim status As MembershipCreateStatus _provider.CreateUser(userName, password, email, Nothing, Nothing, True, Nothing, status) Return status End Function Public Function ChangePassword(ByVal userName As String, ByVal oldPassword As String, ByVal newPassword As String) As Boolean Implements IMembershipService.ChangePassword If String.IsNullOrEmpty(userName) Then Throw New ArgumentException("Value cannot be null or empty.", "username") If String.IsNullOrEmpty(oldPassword) Then Throw New ArgumentException("Value cannot be null or empty.", "oldPassword") If String.IsNullOrEmpty(newPassword) Then Throw New ArgumentException("Value cannot be null or empty.", "newPassword") ' The underlying ChangePassword() will throw an exception rather ' than return false in certain failure scenarios. Try Dim currentUser As MembershipUser = _provider.GetUser(userName, True) Return currentUser.ChangePassword(oldPassword, newPassword) Catch ex As ArgumentException Return False Catch ex As MembershipPasswordException Return False End Try End Function End Class Public Interface IFormsAuthenticationService Sub SignIn(ByVal userName As String, ByVal createPersistentCookie As Boolean) Sub SignOut() End Interface Public Class FormsAuthenticationService Implements IFormsAuthenticationService Public Sub SignIn(ByVal userName As String, ByVal createPersistentCookie As Boolean) Implements IFormsAuthenticationService.SignIn If String.IsNullOrEmpty(userName) Then Throw New ArgumentException("Value cannot be null or empty.", "userName") FormsAuthentication.SetAuthCookie(userName, createPersistentCookie) End Sub Public Sub SignOut() Implements IFormsAuthenticationService.SignOut FormsAuthentication.SignOut() End Sub End Class #End Region #Region "Validation" Public NotInheritable Class AccountValidation Public Shared Function ErrorCodeToString(ByVal createStatus As MembershipCreateStatus) As String ' See http://go.microsoft.com/fwlink/?LinkID=177550 for ' a full list of status codes. Select Case createStatus Case MembershipCreateStatus.DuplicateUserName Return "Username already exists. Please enter a different user name." Case MembershipCreateStatus.DuplicateEmail Return "A username for that e-mail address already exists. Please enter a different e-mail address." Case MembershipCreateStatus.InvalidPassword Return "The password provided is invalid. Please enter a valid password value." Case MembershipCreateStatus.InvalidEmail Return "The e-mail address provided is invalid. Please check the value and try again." Case MembershipCreateStatus.InvalidAnswer Return "The password retrieval answer provided is invalid. Please check the value and try again." Case MembershipCreateStatus.InvalidQuestion Return "The password retrieval question provided is invalid. Please check the value and try again." Case MembershipCreateStatus.InvalidUserName Return "The user name provided is invalid. Please check the value and try again." Case MembershipCreateStatus.ProviderError Return "The authentication provider returned an error. Please verify your entry and try again. If the problem persists, please contact your system administrator." Case MembershipCreateStatus.UserRejected Return "The user creation request has been canceled. Please verify your entry and try again. If the problem persists, please contact your system administrator." Case Else Return "An unknown error occurred. Please verify your entry and try again. If the problem persists, please contact your system administrator. " End Select End Function End Class <AttributeUsage(AttributeTargets.Class, AllowMultiple:=True, Inherited:=False)> _ Public NotInheritable Class PropertiesMustMatchAttribute Inherits ValidationAttribute Private Const _defaultErrorMessage As String = "'{0}' and '{1}' do not match." Private ReadOnly _confirmProperty As String Private ReadOnly _originalProperty As String Private ReadOnly _typeId As New Object() Public Sub New(ByVal originalProperty As String, ByVal confirmProperty As String) MyBase.New(_defaultErrorMessage) _originalProperty = originalProperty _confirmProperty = confirmProperty End Sub Public ReadOnly Property ConfirmProperty() As String Get Return _confirmProperty End Get End Property Public ReadOnly Property OriginalProperty() As String Get Return _originalProperty End Get End Property Public Overrides ReadOnly Property TypeId() As Object Get Return _typeId End Get End Property Public Overrides Function FormatErrorMessage(ByVal name As String) As String Return String.Format(CultureInfo.CurrentUICulture, ErrorMessageString, OriginalProperty, ConfirmProperty) End Function Public Overrides Function IsValid(ByVal value As Object) As Boolean Dim properties As PropertyDescriptorCollection = TypeDescriptor.GetProperties(value) Dim originalValue = properties.Find(OriginalProperty, True).GetValue(value) Dim confirmValue = properties.Find(ConfirmProperty, True).GetValue(value) Return Object.Equals(originalValue, confirmValue) End Function End Class <AttributeUsage(AttributeTargets.Field Or AttributeTargets.Property, AllowMultiple:=False, Inherited:=True)> _ Public NotInheritable Class ValidatePasswordLengthAttribute Inherits ValidationAttribute Private Const _defaultErrorMessage As String = "'{0}' must be at least {1} characters long." Private ReadOnly _minCharacters As Integer = Membership.Provider. MinRequiredPasswordLength Public Sub New() MyBase.New(_defaultErrorMessage) End Sub Public Overrides Function FormatErrorMessage(ByVal name As String) As String Return String.Format(CultureInfo.CurrentUICulture, ErrorMessageString, name, _minCharacters) End Function Public Overrides Function IsValid(ByVal value As Object) As Boolean Dim valueAsString As String = TryCast(value, String) Return (valueAsString IsNot Nothing) AndAlso (valueAsString.Length >= _minCharacters) End Function End Class #End Region
Since we want to include Captcha validation in the Register action, we add a string field representing the Captcha code to the related RegisterModel
class declaration.
The <Required>
attribute specifies that the Captcha code input field cannot be left blank (and which error message to display if it is), while the <Display>
attribute declares the text description used to prompt users to type the Captcha code.
Views\Account\Register.aspx
<%@ Page Language="VB" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage(Of AspNetMvc20CaptchaExampleVBNet.RegisterModel)" %> <%@ Import Namespace="BotDetect.Web.Mvc" %> <%@ Import Namespace="AspNetMvc20CaptchaExampleVBNet" %> <asp:Content ID="registerTitle" ContentPlaceHolderID="TitleContent" runat="server"> Register </asp:Content> <asp:Content ID="BotDetectStylesheets" ContentPlaceHolderID="includes" runat="server"> <link href="<%= BotDetect.Web.CaptchaUrls.Absolute.LayoutStyleSheetUrl %>" rel="stylesheet" type="text/css" /> </asp:Content> <asp:Content ID="registerContent" ContentPlaceHolderID="MainContent" runat="server"> <h2> Create a New Account</h2> <p> Use the form below to create a new account. </p> <p> Passwords are required to be a minimum of <%= ViewData("PasswordLength") %> characters in length. </p> <% Using Html.BeginForm("Register", "Account")%> <%= Html.ValidationSummary(True, "Account creation was unsuccessful. Please correct the errors and try again.")%> <div> <fieldset id="RegisterFields"> <legend>Account Information</legend> <div class="editor-label"> <%= Html.LabelFor(Function(m) m.UserName) %> </div> <div class="editor-field"> <%= Html.TextBoxFor(Function(m) m.UserName) %> <%= Html.ValidationMessageFor(Function(m) m.UserName) %> </div> <div class="editor-label"> <%= Html.LabelFor(Function(m) m.Email) %> </div> <div class="editor-field"> <%= Html.TextBoxFor(Function(m) m.Email) %> <%= Html.ValidationMessageFor(Function(m) m.Email) %> </div> <div class="editor-label"> <%= Html.LabelFor(Function(m) m.Password) %> </div> <div class="editor-field"> <%= Html.PasswordFor(Function(m) m.Password) %> <%= Html.ValidationMessageFor(Function(m) m.Password) %> </div> <div class="editor-label"> <%= Html.LabelFor(Function(m) m.ConfirmPassword) %> </div> <div class="editor-field"> <%= Html.PasswordFor(Function(m) m.ConfirmPassword) %> <%= Html.ValidationMessageFor(Function(m) m.ConfirmPassword) %> </div> <%' add Captcha validation controls to the protected action View Dim registrationCaptcha As MvcCaptcha registrationCaptcha = CaptchaHelper.GetRegistrationCaptcha() If (Not registrationCaptcha.IsSolved) Then%> <div class="editor-label"> <%= Html.Captcha(registrationCaptcha) %> <%= Html.LabelFor(Function(m) m.CaptchaCode)%> </div> <div class="editor-field"> <%= Html.TextBoxFor(Function(m) m.CaptchaCode)%> <%= Html.ValidationMessageFor(Function(m) m.CaptchaCode)%> </div> <% End If%> <p style="width: 195px; text-align: right;"> <input type="submit" value="Register"/> </p> </fieldset> </div> <% End Using%> </asp:Content>
BotDetect stylesheets are included in the generated page Header using the includes
content placeholder defined in the Master page.
To keep View code simple, we delegate MvcCaptcha
instance creation to a helper class, and use it along with Model fields to generate the required markup using straightforward HtmlHelper
calls.
Since we want to avoid re-displaying the Captcha challenge to users after they solve it, we only call the markup generation code if the IsSolved
property is not set by a previous successful Captcha validation.
Views\Shared\Site.Master
<%@ Master Language="VB" Inherits="System.Web.Mvc.ViewMasterPage" %> <!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> <asp:ContentPlaceHolder ID="TitleContent" runat="server" /> </title> <link href="../../Content/Site.css" rel="stylesheet" type="text/css" /> <asp:ContentPlaceHolder ID="includes" runat="server" /> </head> <body> <div class="page"> <div id="header"> <div id="title"> <h1> BotDetect CAPTCHA ASP.NET MVC 2.0 Example</h1> </div> <div id="logindisplay"> <% Html.RenderPartial("LogOnUserControl")%> </div> <div id="menucontainer"> <ul id="menu"> <li> <%= Html.ActionLink("Home", "Index", "Home")%></li> <li> <%= Html.ActionLink("About", "About", "Home")%></li> </ul> </div> </div> <div id="main"> <asp:ContentPlaceHolder ID="MainContent" runat="server" /> <div id="footer"> </div> </div> </div> </body> </html>
To allow easy inclusion of BotDetect stylesheets into Views which require them, the includes
content placeholder should be declared in the Master page header.
Controllers\AccountController.vb
Imports System.Diagnostics.CodeAnalysis Imports System.Security.Principal Imports System.Web.Routing Imports BotDetect.Web.Mvc <HandleError()> _ Public Class AccountController Inherits System.Web.Mvc.Controller Private formsServiceValue As IFormsAuthenticationService Private membershipServiceValue As IMembershipService Public Property FormsService() As IFormsAuthenticationService Get Return formsServiceValue End Get Set(ByVal value As IFormsAuthenticationService) formsServiceValue = value End Set End Property Public Property MembershipService() As IMembershipService Get Return membershipServiceValue End Get Set(ByVal value As IMembershipService) membershipServiceValue = value End Set End Property Protected Overrides Sub Initialize(ByVal requestContext As RequestContext) If FormsService Is Nothing Then FormsService = New FormsAuthenticationService() If MembershipService Is Nothing Then MembershipService = New AccountMembershipService() MyBase.Initialize(requestContext) End Sub ' ************************************** ' URL: /Account/LogOn ' ************************************** Public Function LogOn() As ActionResult Return View() End Function <HttpPost()> _ Public Function LogOn(ByVal model As LogOnModel, ByVal returnUrl As String) As ActionResult If ModelState.IsValid Then If MembershipService.ValidateUser(model.UserName, model.Password) Then FormsService.SignIn(model.UserName, model.RememberMe) If Not String.IsNullOrEmpty(returnUrl) Then Return Redirect(returnUrl) Else Return RedirectToAction("Index", "Home") End If Else ModelState.AddModelError("", "The user name or password provided is incorrect.") End If End If ' If we got this far, something failed, redisplay form Return View(model) End Function ' ************************************** ' URL: /Account/LogOff ' ************************************** Public Function LogOff() As ActionResult FormsService.SignOut() Return RedirectToAction("Index", "Home") End Function ' ************************************** ' URL: /Account/Register ' ************************************** Public Function Register() As ActionResult ViewData("PasswordLength") = MembershipService.MinPasswordLength ' when the View is accessed directly and not posted, we clear any ' remembered CAPTCHA solving state. ' The users only have to solve the CAPTCHA once within a single ' registration, but if they reload the Register page later, ' it is shown again. ' Otherwise, they could register an unlimited number of accounts ' within a single Session after solving the CAPTCHA only once. MvcCaptcha.ResetCaptcha("RegistrationCaptcha") Return View() End Function <HttpPost()> _ <CaptchaValidationActionFilter("CaptchaCode", "RegistrationCaptcha", "Your input doesn't match displayed characters.")> _ Public Function Register(ByVal model As RegisterModel) As ActionResult If ModelState.IsValid Then ' Attempt to register the user Dim createStatus As MembershipCreateStatus = MembershipService.CreateUser( model.UserName, model.Password, model.Email) If createStatus = MembershipCreateStatus.Success Then FormsService.SignIn(model.UserName, False) Return RedirectToAction("Index", "Home") Else ModelState.AddModelError("", AccountValidation.ErrorCodeToString(createStatus)) End If End If ' If we got this far, something failed, redisplay form ViewData("PasswordLength") = MembershipService.MinPasswordLength Return View(model) End Function ' ************************************** ' URL: /Account/ChangePassword ' ************************************** <Authorize()> _ Public Function ChangePassword() As ActionResult ViewData("PasswordLength") = MembershipService.MinPasswordLength Return View() End Function <Authorize()> _ <HttpPost()> _ Public Function ChangePassword(ByVal model As ChangePasswordModel) As ActionResult If ModelState.IsValid Then If MembershipService.ChangePassword(User.Identity.Name, model.OldPassword, model.NewPassword) Then Return RedirectToAction("ChangePasswordSuccess") Else ModelState.AddModelError("", "The current password is incorrect or the new password is invalid.") End If End If ' If we got this far, something failed, redisplay form ViewData("PasswordLength") = MembershipService.MinPasswordLength Return View(model) End Function ' ************************************** ' URL: /Account/ChangePasswordSuccess ' ************************************** Public Function ChangePasswordSuccess() As ActionResult Return View() End Function End Class
To add Captcha validation to the Register action Controller code, we perform a single line of setup in the Register
action when the user GETs it, and execute the <CaptchaValidationActionFilter>
filter when the user POSTs it.
The filter attribute will automatically add the appropriate ModelState
error if the Captcha code input doesn't match the code displayed to the user in the Captcha picture.
CaptchaHelper.vb
Imports BotDetect Imports BotDetect.Web Imports BotDetect.Web.UI Imports BotDetect.Web.Mvc Public Class CaptchaHelper Public Shared Function GetRegistrationCaptcha() As MvcCaptcha ' create the control instance Dim registrationCaptcha As MvcCaptcha = _ New MvcCaptcha("RegistrationCaptcha") registrationCaptcha.UserInputID = "CaptchaCode" ' all Captcha properties are set in this event handler AddHandler WebFormsCaptcha.InitializedWebCaptcha, _ AddressOf RegistrationCaptcha_InitializedWebCaptcha Return registrationCaptcha End Function ' event handler used for Captcha control property randomization Public Shared Sub RegistrationCaptcha_InitializedWebCaptcha( _ ByVal sender As Object, _ ByVal e As BotDetect.InitializedWebCaptchaEventArgs) If (e.CaptchaId <> "RegistrationCaptcha") Then Return End If Dim registrationCaptcha As Captcha = TryCast(sender, Captcha) ' fixed Captcha settings registrationCaptcha.ImageSize = New System.Drawing.Size(200, 50) registrationCaptcha.CodeLength = 4 ' randomized Captcha settings registrationCaptcha.ImageStyle = CaptchaRandomization.GetRandomImageStyle() registrationCaptcha.SoundStyle = CaptchaRandomization.GetRandomSoundStyle() End Sub End Class
Captcha instance creation and property setting is encapsulated in this simple helper class. This separation allows application Views to stay simple regardless of the amount of Captcha customization chosen.
Global.asax.vb
' Note: For instructions on enabling IIS6 or IIS7 classic mode, ' visit http://go.microsoft.com/?LinkId=9394802 Public Class MvcApplication Inherits System.Web.HttpApplication Shared Sub RegisterRoutes(ByVal routes As RouteCollection) routes.IgnoreRoute("{resource}.axd/{*pathInfo}") ' BotDetect requests must not be routed routes.IgnoreRoute("{*botdetect}", New With {.botdetect = "(.*) BotDetectCaptcha\.ashx"}) ' MapRoute takes the following parameters, in order: ' (1) Route name ' (2) URL with parameters ' (3) Parameter defaults routes.MapRoute( _ "Default", _ "{controller}/{action}/{id}", _ New With {.controller = "Account", .action = "Register", . id = UrlParameter.Optional} _ ) End Sub Sub Application_Start() AreaRegistration.RegisterAllAreas() RegisterRoutes(RouteTable.Routes) End Sub End Class
Since all BotDetect requests are handled by the BotDetect HttpHandler
, ASP.NET Url Routing must be configured to ignore BotDetect requests, which can be achieved by a single line of code in Global.asax
code-behind.
Web.config
<?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> <!-- Register the BotDetect configuration section --> <section name="botDetect" requirePermission="false" type="BotDetect.Configuration.BotDetectConfigurationSection, BotDetect"/> </configSections> <connectionStrings> <add name="ApplicationServices" connectionString="data source=.\SQLEXPRESS; Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true" providerName="System.Data.SqlClient"/> </connectionStrings> <system.web> <compilation debug="false"> <assemblies> <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.Web.Abstractions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> <add assembly="System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> <add assembly="System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> </assemblies> </compilation> <authentication mode="Forms"> <forms loginUrl="~/Account/LogOn" timeout="2880" /> </authentication> <membership> <providers> <clear/> <add name="AspNetSqlMembershipProvider" type="System.Web.Security. SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="ApplicationServices" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" passwordFormat="Hashed" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" passwordStrengthRegularExpression="" applicationName="/"/> </providers> </membership> <profile> <providers> <clear/> <add name="AspNetSqlProfileProvider" type="System.Web.Profile. SqlProfileProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="ApplicationServices" applicationName="/"/> </providers> </profile> <roleManager enabled="false"> <providers> <clear/> <add connectionStringName="ApplicationServices" applicationName="/" name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/> <add applicationName="/" name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/> </providers> </roleManager> <!-- make sure Session State is enabled --> <pages enableSessionState="true"> <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> <namespaces> <add namespace="System.Web.Mvc"/> <add namespace="System.Web.Mvc.Ajax"/> <add namespace="System.Web.Mvc.Html"/> <add namespace="System.Web.Routing"/> <add namespace="System.Collections.Generic"/> <!-- add BotDetect namespaces for coding convenience --> <add namespace="BotDetect"/> <add namespace="BotDetect.Web"/> <add namespace="BotDetect.Web.UI"/> <add namespace="BotDetect.Web.Mvc"/> </namespaces> </pages> <!-- configure Session State for BotDetect use --> <sessionState mode="InProc" cookieless="AutoDetect" timeout="20" sessionIDManagerType="BotDetect.Web.CustomSessionIdManager, BotDetect"/> <httpHandlers> <remove verb="*" path="*.asmx"/> <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"/> <add verb="*" path="*.mvc" validate="false" type="System.Web.Mvc. MvcHttpHandler, System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> <!-- register HttpHandler used for BotDetect Captcha requests --> <add verb="GET" path="BotDetectCaptcha.ashx" type="BotDetect.Web.CaptchaHandler, BotDetect"/> </httpHandlers> <httpModules> <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System. Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> </httpModules> </system.web> <system.codedom> <compilers> <compiler language="c#;cs;csharp" extension=".cs" warningLevel="4" type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <providerOption name="CompilerVersion" value="v3.5"/> <providerOption name="WarnAsError" value="false"/> </compiler> <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" warningLevel="4" type="Microsoft.VisualBasic.VBCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <providerOption name="CompilerVersion" value="v3.5"/> <providerOption name="OptionInfer" value="true"/> <providerOption name="WarnAsError" value="false"/> </compiler> </compilers> </system.codedom> <system.web.extensions/> <system.webServer> <validation validateIntegratedModeConfiguration="false"/> <modules runAllManagedModulesForAllRequests="true"> <remove name="ScriptModule"/> <remove name="UrlRoutingModule"/> <add name="ScriptModule" preCondition="managedHandler" type="System.Web. Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> </modules> <handlers> <remove name="WebServiceHandlerFactory-Integrated"/> <remove name="ScriptHandlerFactory"/> <remove name="ScriptHandlerFactoryAppServices"/> <remove name="ScriptResource"/> <remove name="MvcHttpHandler"/> <remove name="UrlRoutingHandler"/> <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"/> <add name="MvcHttpHandler" preCondition="integratedMode" verb="*" path="*. mvc" type="System.Web.Mvc.MvcHttpHandler, System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> <add name="UrlRoutingHandler" preCondition="integratedMode" verb="*" path="UrlRouting.axd" type="System.Web.HttpForbiddenHandler, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/> <!-- register HttpHandler used for BotDetect Captcha requests --> <remove name="BotDetectCaptchaHandler"/> <add name="BotDetectCaptchaHandler" preCondition="integratedMode" verb="GET" path="BotDetectCaptcha.ashx" type="BotDetect.Web.CaptchaHandler, BotDetect"/> </handlers> </system.webServer> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" /> <bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0" /> </dependentAssembly> </assemblyBinding> </runtime> <botDetect helpLinkEnabled="true" helpLinkMode="image" /> </configuration>
The application's web.config
file includes the standard BotDetect HttpHandler
and Session state configuration elements.
Current BotDetect Versions
-
BotDetect ASP.NET CAPTCHA
2019-07-22v4.4.2 -
BotDetect Java CAPTCHA
2019-07-22v4.0.Beta3.7 -
BotDetect PHP CAPTCHA
2019-07-22v4.2.5