How To Add BotDetect CAPTCHA Protection to ASP.NET MVC 5.0 Applications

BotDetect ASP.NET Captcha Simple API protection can be added to your ASP.NET MVC 5.0 applications using the MvcSimpleCaptcha class, a BotDetect HtmlHelper and a custom ActionFilterAttribute implemented in the BotDetect.Web.Mvc.dll assembly.

First Time Here?

Check the BotDetect ASP.NET MVC Captcha Simple API 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 examples coming with the BotDetect installation.

You can reuse the example projects source code (available for both C# and VB.NET) that fits your application requirements.

CAPTCHA Integration Steps

When adding BotDetect CAPTCHA to an ASP.NET MVC 5.0 application:
  1. Display a Captcha challenge on the Asp.Net MVC View
  2. Check is the visitor a human in the Controller action
  3. Further SimpleCaptcha 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 ExampleCaptcha 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 SimpleCaptcha 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.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)\Captcha Inc\BotDetect 4 CAPTCHA Component\Asp.Net\.NET\bin\ folder.

Reference SQLite Assembly

By default, BotDetect ASP.NET CAPTCHA Simple API uses SQLite as the default persistence provider for storing captcha data, so you need to ensure SQLite assembly is referenced in your project. Here is where you can find the SQLite installation guide. Or check any Simple API examples that are installed with BotDetect.

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.

Fortunatelly, it is easy to resolve these errors with a binding redirect in your web.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-5.0.0.0" newVersion="5.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.Mvc.MvcSimpleCaptcha Instance

SimpleCaptcha objects in ASP.NET MVC applications are represented by the MvcSimpleCaptcha class, and they can be rendered using a HtmlHelper extension method defined in the same assembly. To use them, your View should first import the BotDetect.Web.Mvc namespace.

Then, you can add a Captcha challenge to the View by rendering a Html.Label with the SimpleCaptcha instructions for the user, a Html.SimpleCaptcha with the MvcSimpleCaptcha object instance, and a Html.TextBox in which the user is to type the Captcha code:

@using BotDetect.Web.Mvc;

  […]

@Html.Label("CaptchaCode", "Retype the code from the picture:")
@{ MvcSimpleCaptcha exampleCaptcha = new MvcSimpleCaptcha("ExampleCaptcha"); }
@Html.SimpleCaptcha(exampleCaptcha)
@Html.TextBox("CaptchaCode")

Configure Captcha options

Configure captcha options in botdetect.xml configuration file. By default, this file is located at the root of your project.

<?xml version="1.0" encoding="UTF-8"?>
<botdetect xmlns="https://captcha.com/schema/net"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="https://captcha.com/schema/net 
     https://captcha.com/schema/net/botdetect-4.4.0.xsd">

  <captchaStyles>
    <captchaStyle>
      <name>ExampleCaptcha</name>
      <userInputID>CaptchaCode</userInputID>
      <codeLength>3-5</codeLength>
    </captchaStyle>
  </captchaStyles>

</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 three-step process:

1. Base HttpHandler Registration

  • Locate the <system.web> -> <httpHandlers> section of the web.config file.
  • Add the following BotDetect handler registration to this section:
    <!-- Register the HttpHandler used for BotDetect Simple API requests -->
    <add verb="GET" path="BotDetectCaptcha.ashx" 
        type="BotDetect.Web.SimpleCaptchaHandler, BotDetect"/>

2. IIS 7.0+ HttpHandler Registration

  • Locate the <system.webServer> -> <handlers> section of the web.config file.
  • Add the following BotDetect handler registration to this section:
    <!-- Register the HttpHandler used for BotDetect Simple API requests
      (IIS 7.0+) -->
    <remove name="BotDetectCaptchaHandler"/>
    <add name="BotDetectCaptchaHandler" preCondition="integratedMode"
        verb="GET" path="BotDetectCaptcha.ashx"
        type="BotDetect.Web.SimpleCaptchaHandler, BotDetect"/>

3. Exclude BotDetect HttpHandler Requests From ASP.NET Routing

Once the BotDetect SimpleCaptcha 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 SimpleCaptcha should be displayed when you open your form in a browser:

BotDetect CAPTCHA added to an ASP.NET form

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 SimpleCaptcha challenge is displayed on your View, the Controller code processing submissions can check if the SimpleCaptcha 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 SimpleCaptchaValidation attribute just needs to be passed the names of the Captcha instance and Captcha code textbox used.

Mark the Protected Controller Action with the SimpleCaptchaValidation Attribute

The SimpleCaptchaValidation attribute takes three parameters:

  • Captcha code textbox name
  • MvcSimpleCaptcha instance name
  • the error message that will be displayed when Captcha validation fails
[C#]

//
// POST: /ExampleController/ExampleAction

[HttpPost]
[AllowAnonymous]
[SimpleCaptchaValidation("CaptchaCode", "ExampleCaptcha", "Incorrect CAPTCHA code!")]
public ActionResult ExampleAction(ExampleModel model)
{
    if (ModelState.IsValid)
    {    
    
        […]
    
[VB.NET]

'
' POST: /ExampleController/ExampleAction

<HttpPost()> _
<AllowAnonymous()> _
<SimpleCaptchaValidation("CaptchaCode", "ExampleCaptcha", "Incorrect CAPTCHA code!")> _
Public Function ExampleAction(ByVal model As ExampleModel) 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 SimpleCaptchaValidation attribute if Captcha validation fails.

(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#]
    
[SimpleCaptchaValidation("CaptchaCode", "ExampleCaptcha", "Incorrect CAPTCHA code!")]
public ActionResult ExampleAction(ExampleModel model, bool captchaValid)
{
    if (captchaValid)
    {
    
        […]

[VB.NET]

<SimpleCaptchaValidation("CaptchaCode", "ExampleCaptcha", "Incorrect CAPTCHA code!")> _
Public Function ExampleAction(ByVal model As ExampleModel, _
    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 5.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 5.0 Internet application Captcha Simple API example.

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 5.0 jQuery Ajax Captcha Simple API example.

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 Simple API example.

III. Further CAPTCHA Customization and Options

BotDetect ASP.NET Captcha Simple API allows detailed customization of many Captcha properties, and you can read more about them in the BotDetect Captcha Simple API configuration How To.