How To Add BotDetect CAPTCHA Protection to ASP.NET WebForms Applications
<BotDetect:WebFormsCaptcha>
custom Web Control. Displaying the Captcha challenge can be as simple as:
<BotDetect:WebFormsCaptcha ID="ExampleCaptcha" UserInputID="CaptchaCode" runat="server" />and checking user input when the form is submitted:
bool isHuman = ExampleCaptcha.Validate(userInput);
First Time Here?
Check the BotDetect ASP.NET WebForms Captcha Quickstart for key integration steps.
You can also see how BotDetect Captcha protection has been added to various kinds of ASP.NET forms and projects by running the BotDetect Captcha ASP.NET integration code examples coming with the BotDetect installation.
You can reuse the example projects source code (both C# and VB.NET are available) that fits your application requirements.
CAPTCHA Integration Steps
When adding BotDetect Captcha protection to an ASP.NET WebForms application:
- Display a Captcha challenge on the Asp.Net form
- Check is the visitor a human on form PostBack
- Further Captcha customization and options
I. Display a CAPTCHA Challenge on the ASP.NET Form
Before protecting a form action in your ASP.NET WebForms application with BotDetect Captcha, you should decide how to call the Captcha instance and the related textbox you will use. In this guide, we will use ExampleCaptcha
and CaptchaCode
. If you plan to protect multiple forms within the same ASP.NET WebForms application, you should take care to give each Captcha instance a different name (e.g. LoginCaptcha
, RegisterCaptcha
, CommentCaptcha
etc.).
To display a Captcha test on a form in an ASP.NET WebForms application, we must reference the BotDetect assembly, add several controls to the form's .aspx
source, and register both the tag prefix used by BotDetect controls and the HttpHandler
used to display Captcha images.
Reference the BotDetect.dll
Assembly
Run the following command in the Package Manager Console:
PM> Install-Package Captcha
After the command execution, the references to the BotDetect.dll
, BotDetect.Web.Mvc.dll
, and
System.Data.SQLite.dll
assemblies will be added to your project.
If your project is not going to be using the Simple API, the System.Data.SQLite.dll
assembly reference can be safely removed from it.
Add a <BotDetect:WebFormsCaptcha>
Control to the Form
On the ASP.NET form you want to protect with BotDetect Captcha, add the following ASP.NET controls:
- A
BotDetect:WebFormsCaptcha
control which will display the Captcha challenge - An
asp:TextBox
for the Captcha code user input - An
asp:Label
for the textbox, displaying Captcha instructions - An
asp:Label
which will display Captcha validation errors
The resulting fragment in your .aspx
file could look like:
<asp:Label ID="CaptchaLabel" runat="server" AssociatedControlID="CaptchaCode"> Retype the characters from the picture: </asp:Label> <BotDetect:WebFormsCaptcha ID="ExampleCaptcha" UserInputID="CaptchaCode" runat="server" /> <asp:TextBox ID="CaptchaCode" runat="server" /> <asp:Label ID="CaptchaErrorLabel" runat="server"/>
Register the BotDetect
Tag Prefix
For your form to recognize the Captcha
control as used above, the BotDetect:
control tag prefix must be registered. The simplest way to achieve this is to add the following declaration to the top of your form .aspx
source, just below the <%@ Page
directive:
<%@ Register Assembly="BotDetect" Namespace="BotDetect.Web.UI" TagPrefix="BotDetect" %>
(Option) Global BotDetect
Tag Prefix Registration
Alternatively, if you want to use the BotDetect:WebFormsCaptcha
control on multiple forms within a single ASP.NET WebForms application, and want to avoid having to paste the above <%@ Register
directive on each form individually, you can register the BotDetect
tag prefix in your application's Web.config
file:
- Locate the
<system.web> -> <pages> -> <controls>
section -
Add the following line to its bottom (just before the closing
</controls>
tag):<!-- Register the BotDetect tag prefix for easier use in all pages --> <add assembly="BotDetect" namespace="BotDetect.Web.UI" tagPrefix="BotDetect"/>
Register the BotDetect HttpHandler
for CAPTCHA Requests
BotDetect uses a special HttpHandler
for Captcha requests (Captcha images, sounds, resources...), which needs to be registered in your application before Captcha images will be displayed. This registration is a two-step process:
1. Base HttpHandler
Registration
- Locate the
<system.web> -> <httpHandlers>
section of theweb.config
file. -
Add the following BotDetect handler registration to this section:
<!-- Register the HttpHandler used for BotDetect Captcha requests --> <add verb="GET" path="BotDetectCaptcha.ashx" type="BotDetect.Web.CaptchaHandler, BotDetect"/>
2. IIS 7.0+ HttpHandler
Registration
- Locate the
<system.webServer> -> <handlers>
section of theweb.config
file. -
Add the following BotDetect handler registration to this section:
<!-- 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"/>
Once all of these steps have been performed, the Captcha should be displayed when you open your form in a browser:
If the Captcha image isn't being rendered properly, please check the BotDetect integration FAQ.
II. Check is the Visitor a Human on Form PostBack
Once the Captcha challenge is displayed on your form, the code processing form submissions can check if the Captcha was solved successfully and deny access to bots.
This code needs to access the Captcha and textbox control instances added to the form; ASP.NET Session state must also be enabled before Captcha validation can work.
Add CAPTCHA Validation Logic to Page Code-Behind
When the form is submitted, the Captcha validation result must be checked and the protected action (user registration, comment posting, email sending, ...) only performed if the Captcha test was passed. For example:
[C#] protected void Page_PreRender(object sender, EventArgs e) { if (!IsPostBack) { // initialize the Captcha validation error label CaptchaErrorLabel.Text = "Incorrect CAPTCHA code!"; CaptchaErrorLabel.Visible = false; } // setup client-side input processing ExampleCaptcha.UserInputID = CaptchaCode.ClientID; if (IsPostBack) { // validate the Captcha to check we're not dealing with a bot string userInput = CaptchaCode.Text; bool isHuman = ExampleCaptcha.Validate(userInput); CaptchaCode.Text = null; // clear previous user input if (isHuman) { CaptchaErrorLabel.Visible = false; // TODO: proceed with protected action } else { CaptchaErrorLabel.Visible = true; } } }
[VB.NET] Protected Sub Page_PreRender(ByVal sender As Object, ByVal e As _ System.EventArgs) Handles Me.PreRender If Not IsPostBack Then ' initialize the Captcha validation error label CaptchaErrorLabel.Text = "Incorrect!" CaptchaErrorLabel.Visible = False End If ' setup client-side input processing ExampleCaptcha.UserInputID = CaptchaCode.ClientID If IsPostBack Then ' validate the Captcha to check we're not dealing with a bot Dim userInput As String, isHuman As Boolean userInput = CaptchaCode.Text isHuman = ExampleCaptcha.Validate(userInput) CaptchaCode.Text = "" ' clear previous user input If isHuman Then CaptchaErrorLabel.Visible = False ' TODO: proceed with protected action Else CaptchaErrorLabel.Visible = True End If End If End Sub
Getting the CAPTCHA Validation Result
The user input for the Captcha code can be read from the textbox you added to the form (called CaptchaCode
in this guide so far), and the boolean result of Captcha validation can be determined by calling the Validate()
method on the Captcha
control instance.
Since it only makes sense to make this check when the form is submitted, this code should be placed within a Page.IsPostBack
check. We should also take care not the validate the same user input more than once, since every Captcha code can only be validated once for security reasons.
For the same reason, there is no point to remembering previous user Captcha code input, so we always clear the textbox value after Captcha validation (regardless of the validation result).
This (and much more) is explained in the BotDetect Captcha validation and security FAQ.
CAPTCHA Validation Failure
If Captcha validation failed, you should display an error message to the user and instruct them to try retyping it again. You should also cancel the protected action that you want only human visitors to have access to.
CAPTCHA Validation Success
If Captcha validation succeeded, the visitor has proven to be a human and not a bot, and you can proceed with the protected action.
(Option) Getting the CAPTCHA Control References Placed in a <ContentLayout>
If you placed the Captcha on the form within a <ContentLayout>
of another ASP.NET control (such as the <asp:Login>
and <asp:CreateUserWizard>
controls), you will not be able to access the textbox and Captcha control instances directly by name as shown above.
In this case, you can use FindControl()
calls on the container to get control instances by name. For example, in case of an ASP.NET login form Captcha placed within a <asp:Login>
control called ExampleLogin
, you would use:
[C#] TextBox CaptchaCode = ExampleLogin.FindControl("CaptchaCode") as TextBox; Captcha ExampleCaptcha = ExampleLogin.FindControl("ExampleCaptcha") as Captcha;
[VB.NET] Dim CaptchaCode As TextBox = _ TryCast(ExampleLogin.FindControl("CaptchaCode"), TextBox) Dim ExampleCaptcha As Captcha = _ TryCast(ExampleLogin.FindControl("ExampleCaptcha"), Captcha)
Or, in case of an ASP.NET registration form Captcha placed within a <asp:CreateUserWizard>
control called RegisterUser
:
[C#] TextBox CaptchaCode = RegisterUser.CreateUserStep. ContentTemplateContainer.FindControl("CaptchaCode") as TextBox; Captcha ExampleCaptcha = RegisterUser.CreateUserStep. ContentTemplateContainer.FindControl("ExampleCaptcha") as Captcha;
[VB.NET] Dim CaptchaCode As TextBox = TryCast( _ RegisterUser.CreateUserStep.ContentTemplateContainer.FindControl( _ "CaptchaCode"), TextBox) Dim ExampleCaptcha As Captcha = TryCast( _ RegisterUser.CreateUserStep.ContentTemplateContainer.FindControl( _ "ExampleCaptcha"), Captcha)
In all cases, you can then get the Captcha validation result using those control instances as shown above. You can see an example of this code in the ASP.NET WebForms Captcha register form example code.
Configure ASP.NET Session State
BotDetect Captcha validation requires ASP.NET Session state – generated random Captcha codes have to be stored on the server and compared to the user input. Also, to ensure Captcha sounds work properly in all browsers, a custom SessionIDManager
(implementing an optional but recommended improvement) should be registered.
- In the
<system.web>
section of theweb.config
file, locate the<pages>
element and set theenableSessionState
attribute:<pages enableSessionState="true">
- In the
<system.web>
section of theweb.config
file, locate the<sessionState>
element if it exists, or add it if it doesn't. -
Add the following attribute to the declaration:
sessionIDManagerType="BotDetect.Web.CustomSessionIdManager, BotDetect"
<sessionState mode="InProc" cookieless="AutoDetect" timeout="20" sessionIDManagerType="BotDetect.Web.CustomSessionIdManager, BotDetect"/>
You can use a different Session State mode or options, since BotDetect works with all of them. For more information about BotDetect and ASP.NET Session state, and debugging tips in case the Captcha validation is failing even when you type the correct Captcha code, please check the BotDetect persistence options FAQ.
(Option) Including the CAPTCHA Validation Result in Page.IsValid
The above Captcha validation code is based on getting the Captcha validation result directly as a boolean. It is also possible to integrate it with ASP.NET WebForms validation of other form fields using a <asp:CustomValidator>
control.
This would allow you to use the Captcha validation result in a validation summary, and have your code only check the overall validity of the whole form (instead of checking the Captcha separately from other form fields).
For example, you could attach the following control to the Captcha code textbox:
<asp:CustomValidator runat="server" ID="CaptchaValidator" ControlToValidate="CaptchaCode" ErrorMessage="Incorrect CAPTCHA code!" OnServerValidate="CaptchaValidator_ServerValidate" />
and then place the Captcha validation code within the CaptchaValidator_ServerValidate
event handler in form code-behind:
[C#] protected void CaptchaValidator_ServerValidate(object source, ServerValidateEventArgs args) { // validate the Captcha to check we're not dealing with a bot args.IsValid = ExampleCaptcha.Validate(args.Value); CaptchaCode.Text = null; // clear previous user input }
[VB.NET] Protected Sub CaptchaValidator_ServerValidate(ByVal source As Object, ByVal args As ServerValidateEventArgs) ' validate the Captcha to check we're not dealing with a bot args.IsValid = RegisterCaptcha.Validate(args.Value) CaptchaCode.Text = Nothing ' clear previous user input End Sub
The registration form Captcha shown in the ASP.NET WebForms application template Captcha example uses both a <asp:RequiredFieldValidator>
and a <asp:CustomValidator>
to ensure only human visitors can register new user accounts.
A variant of this code is also implemented by the <BotDetect:CaptchaValidator>
control and shown in the ASP.NET Captcha Validator example.
III. Further CAPTCHA Customization and Options
BotDetect ASP.NET Captcha allows detailed customization of many Captcha properties, and you can read more about them in the BotDetect Captcha configuration How To.
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