How To Add BotDetect CAPTCHA Protection to ASP.NET MVC 4.0 Applications (BotDetect v3.0; deprecated)
ASP.NET MVC 4.0 applications using the MvcCaptcha
class, a BotDetect HtmlHelper
and a custom ActionFilterAttribute
implemented in the BotDetect.Web.UI.Mvc.dll
assembly.
First Time Here?
Check the BotDetect ASP.NET MVC Captcha Quickstart for key integration steps.
You can also see how BotDetect Captcha protection has been added to the starting ASP.NET MVC application by running the BotDetect Captcha ASP.NET MVC integration code samples coming with the BotDetect installation.
You can reuse the sample projects source code (available for both C# and VB.NET, as well as both Razor and ASPX view engines) that fits your application requirements.
CAPTCHA Integration Steps
When adding BotDetect CAPTCHA to an ASP.NET MVC 4.0 application:- Display a Captcha challenge on the Asp.Net MVC View
- Check is the visitor a human in the Controller action
- Mark the protected Controller action with the
CaptchaValidation
attribute - Configure Asp.Net Session state
- Mark the protected Controller action with the
- Further Captcha customization and options
I. Display a CAPTCHA Challenge on the ASP.NET MVC View
Before protecting a Controller action in your ASP.NET MVC 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 SampleCaptcha
and CaptchaCode
. If you plan to protect multiple Controller actions within the same ASP.NET MVC application, you should take care to give each Captcha instance a different name (e.g. LoginCaptcha
, RegisterCaptcha
, CommentCaptcha
etc.).
You will also need to register a HttpHandler
that will handle Captcha requests, and exclude it from ASP.NET Routing.
Reference BotDetect Assemblies
ASP.NET MVC applications should reference both the base BotDetect.dll
assembly and the ASP.NET MVC-specific BotDetect.Web.UI.Mvc.dll
assembly. If you didn't change the installation folder during BotDetect setup, they can both be found in the C:\Program Files (x86)\Lanapsoft\BotDetect 3 CAPTCHA Component\Asp.Net\v4.5\
folder.
Resolving ASP.NET MVC Dependencies
The same BotDetect assembly will work with all versions of ASP.NET MVC (for example, ASP.NET MVC 3.0, ASP.NET MVC 4.0, ASP.NET MVC 5.0 etc.). However, since the BotDetect assembly can only be built with a reference to a single ASP.NET MVC version, you might get runtime errors if the version of ASP.NET MVC you are using doesn't match the one BotDetect was built with.
Fortunately, it is easy to resolve these errors with a binding redirect in yourweb.config
file:
<runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" /> <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" /> </dependentAssembly> </assemblyBinding> </runtime>
Just specify the ASP.NET MVC version you are using in the newVersion
configuration attribute, and any MVC dependency-related errors should be resolved.
Create and Render a BotDetect.Web.UI.Mvc.MvcCaptcha
Instance
Captcha objects in ASP.NET MVC applications are represented by the HtmlHelper
extension method defined in the same assembly. To use them, your View should first import the BotDetect.Web.UI.Mvc
namespace.
Then, you can add a Captcha challenge to the View by rendering a Html.Label
with the Captcha instructions for the user, a Html.Captcha
with the MvcCaptcha
object instance, and a Html.TextBox
in which the user is to type the Captcha code:
[ASPX View] <%@ Import namespace="BotDetect.Web.UI.Mvc" %> […] <%: Html.Label("CaptchaCode", "Retype the code from the picture:") %> <% MvcCaptcha sampleCaptcha = new MvcCaptcha("SampleCaptcha"); %> <%: Html.Captcha(sampleCaptcha) %> <%: Html.TextBox("CaptchaCode") %>
[Razor View] @using BotDetect.Web.UI.Mvc; […] @Html.Label("CaptchaCode", "Retype the code from the picture:") @{ MvcCaptcha sampleCaptcha = new MvcCaptcha("SampleCaptcha"); } @Html.Captcha(sampleCaptcha) @Html.TextBox("CaptchaCode")
(Option) Encapsulate MvcCaptcha
Instance Creation in a Helper Class
Since the MvcCaptcha
object exposes a number of Captcha properties, the code that initializes it will often grow much longer than a single line with the constructor call (as shown in the View code above).
Adding those additional lines directly to the View would add unnecessary length and complexity to View code, and mixing code that deals with different concerns (View composition and Captcha object initialization in this case) is never a good practice. It is a much better idea to separate Captcha object creation in a specialized helper class, and keep MvcCaptcha
instance access in a single line of View code.
For example, if you added the following class declaration to your ASP.NET MVC application's App_Code
folder:
[C#] public static class CaptchaHelper { public static MvcCaptcha GetSampleCaptcha() { // create the control instance MvcCaptcha sampleCaptcha = new MvcCaptcha("SampleCaptcha"); // set up client-side processing of the Captcha code input textbox sampleCaptcha.UserInputClientID = "CaptchaCode"; return sampleCaptcha; } }
[VB.NET] Public Class CaptchaHelper Public Shared Function GetSampleCaptcha() As MvcCaptcha ' create the control instance Dim sampleCaptcha As MvcCaptcha = New MvcCaptcha("SampleCaptcha") ' set up client-side processing of the Captcha code input textbox sampleCaptcha.UserInputClientID = "CaptchaCode" Return sampleCaptcha End Function End Class
you could replace the sampleCaptcha = new MvcCaptcha("SampleCaptcha")
call in your View code with sampleCaptcha = CaptchaHelper.GetSampleCaptcha()
. That way, the code initializing the Captcha object can grow arbitrarily large without cluttering the View. Of course, you would also need to import your application's namespace in the View to be able to access the CaptchaHelper
class.
Include the BotDetect CAPTCHA Layout StyleSheet
Since the Html markup generated by BotDetect includes a number of different elements (the Captcha image, the icons for Captcha reloading and Captcha sound playing, the Captcha help link etc.), there are some CSS declarations which need to be included for those elements to display correctly.
The best place to include CSS style declarations is in the page <head>
, and since you are controlling the View markup, you know best where exactly to add them. The BotDetect layout stylesheet can be included with the following declaration:
[ASPX View] <link href="<%: Url.Content("~/" + BotDetect.Web.CaptchaUrls. LayoutStyleSheetUrl) %>" rel="stylesheet" type="text/css" />
[Razor View] <link href="@BotDetect.Web.CaptchaUrls.Absolute.LayoutStyleSheetUrl" rel="stylesheet" type="text/css" />
If your View generates its own <head>
section, you can add these declaration directly in View code. If you're using an ASPX Master page (or a Razor Layout) and individual Views only generate main content, you can add them to the ASPX Master page (or Razor Layout).
Even better, your Master page can include an <asp:ContentPlaceHolder>
for <head>
includes (or your Razor Layout can use a @RenderSection()
call for the same purpose) – and then individual Views can add their required declarations there without affecting other Views. You can see an example of this last approach in the appropriate BotDetect ASP.NET MVC Captcha sample using Razor Views.
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 three-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"/>
3. Exclude BotDetect HttpHandler
Requests From ASP.NET Routing
Once the BotDetect Captcha HttpHandler
is registered in your application's Web.config
file, you will also need to exclude it from ASP.NET Routing. Since routing rules try to map all incoming requests to a Controller/Action/Params
pattern, and BotDetect requests do not match it, Captcha images will not display correctly until routing rules are told to ignore BotDetect requests.
Go to your application's App_Start/RouteConfig.cs
(or App_Start/RouteConfig.vb
) file and add the following bolded line:
[C#] public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); // BotDetect requests must not be routed routes.IgnoreRoute("{*botdetect}", new { botdetect = @"(.*)BotDetectCaptcha\.ashx" }); […]
[VB.NET] Public 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"}) […]
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 in the Controller Action
Once the Captcha challenge is displayed on your View, the Controller code processing submissions can check if the Captcha was solved successfully and deny access to bots.
Captcha validation is encapsulated within an ActionFilterAttribute
that can be added to actions accepting HtppVerbs.Post
requests; the CaptchaValidation
attribute just needs to be passed the names of the Captcha instance and Captcha code textbox used. ASP.NET Session state must also be enabled before Captcha validation can work.
Mark the Protected Controller Action with the CaptchaValidation
Attribute
The CaptchaValidation
attribute takes three parameters:
- Captcha code textbox name
MvcCaptcha
instance name- the error message that will be displayed when Captcha validation fails
[C#] // // POST: /SampleController/SampleAction [HttpPost] [AllowAnonymous] [CaptchaValidation("CaptchaCode", "SampleCaptcha", "Incorrect CAPTCHA code!")] public ActionResult SampleAction(SampleModel model) { if (ModelState.IsValid) { […]
[VB.NET] ' ' POST: /SampleController/SampleAction <HttpPost()> _ <AllowAnonymous()> _ <CaptchaValidation("CaptchaCode", "SampleCaptcha", "Incorrect CAPTCHA code!")> _ Public Function SampleAction(ByVal model As SampleModel) As ActionResult If ModelState.IsValid Then […]
If everything has been configured correctly, the above ActionFilterAttribute
will automatically add the appropriate ModelState
error when Captcha validation fails, and checking ModelState
validity will include the Captcha validation result.
If you are using a validation summary to display Model validation errors, the Captcha validation error will be displayed there as well. If, on the other hand, you are displaying individual server-side validation errors one by one, you can always get the Captcha validation error in your View by the Captcha code textbox name. For example, Html.ValidationMessage("CaptchaCode")
added to the above View code will be empty if Captcha validation succeeded, and will contain the error message defined in the CaptchaValidation
attribute if Captcha validation fails.
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) CAPTCHA Validation Separate From Model State Validation
If, for any reason, you want to check Captcha validity separately from ModelState
, you can simply use an additional action parameter (which must be called captchaValid
) and make the validation logic explicit:
[C#] [CaptchaValidation("CaptchaCode", "SampleCaptcha", "Incorrect CAPTCHA code!")] public ActionResult SampleAction(SampleModel model, bool captchaValid) { if (captchaValid) { […]
[VB.NET] <CaptchaValidation("CaptchaCode", "SampleCaptcha", "Incorrect CAPTCHA code!")> _ Public Function SampleAction(ByVal model As SampleModel, _ ByVal captchaValid As Boolean) As ActionResult If captchaValid Then […]
(Option) Client-Side CAPTCHA Validation
Since the Captcha codes must be stored and checked on the server, pure client-side Captcha validation is not feasible (as explained in the BotDetect FAQ). However, it is possible to improve the usability of your form with Ajax Captcha validation.
CAPTCHA Validation Using ASP.NET MVC 4.0 Unobtrusive Validation
If you're using ASP.NET MVC 4.0 unobtrusive validation, adding the same for Captcha code fields is as simple as adding a few validation configuration rules in a JavaScript include added after the "~/bundles/jqueryval"
ASP.NET MVC script bundle. An example is given in the ASP.NET MVC 4.0 Internet application Captcha sample.
CAPTCHA Validation Using jQuery and JsonResult
Controller Actions
Another MVC-specific way to implement Ajax Captcha validation is to combine jQuery $.getJSON
Ajax requests on the client with the ASP.NET MVC Controller actions with the JsonResult
return type. An example is given in the ASP.NET MVC 4.0 jQuery Ajax Captcha sample.
CAPTCHA Validation Using the jQuery Validate Plugin
If you are using your own field validation functionality based on the jquery.validate.js
plugin, client-side Captcha validation can be implemented using a combination of the required
and remote
validation rules. An example is given in the ASP.NET jQuery Validation Captcha sample.
Built-In Ajax CAPTCHA Validation
If you're using some other client-side validation approach, you can always implement custom Ajax Captcha validation using the built-in Ajax Captcha validation guide.
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.
Please Note
The information on this page is out of date and applies to a deprecated version of BotDetect™ CAPTCHA (v3.0).
An up-to-date equivalent page for the latest BotDetect Captcha release (v4) is BotDetect v4 Captcha documentation index.
General information about the major improvements in the current BotDetect release can be found at the What's New in BotDetect v4.0 page.
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