ASP.NET MVC 4.0 jQuery Ajax CAPTCHA C# Razor Code Sample (BotDetect v3.0; deprecated)
The ASP.NET MVC 4.0 jQuery Ajax Captcha C# Razor sample project shows how to perform Ajax Captcha validation using a jQuery $.getJSON
call on the client combined with an ASP.NET MVC 4.0 JsonResult
Controller action on the server.
First Time Here?
Check the BotDetect ASP.NET MVC Captcha Quickstart for key integration steps.
Both the client-side code (located in Scripts\CheckCaptcha.js
) and the server-side code (Controllers\SampleController.cs
) are very simple, and allow BotDetect Captcha protection to be added in a variety of custom Ajax forms and scenarios.
→ ASP.NET MVC version:
- ASP.NET MVC 5.0
- ASP.NET MVC 4.0
→ .NET programming language:
- C#
- VB.NET
→ View engine:
- ASPX
- Razor
Installed Location
By default, the .NET 4.5 C# Razor version of the ASP.NET MVC 4.0 jQuery Ajax Captcha sample project is installed at:
C:\Program Files\Lanapsoft\BotDetect 3 CAPTCHA Component\Asp.Net\v4.5\WebApp\AspNetMvc40AjaxCaptchaSample\Razor\CSharp
You can also run it from the BotDetect Start Menu:
Programs > Lanapsoft > BotDetect 3 CAPTCHA Component > ASP.NET > DotNET 4.5 Web Applications > Run
- Views\Sample\Index.cshtml
- Controllers\SampleController.cs
- App_Code\CaptchaHelper.cs
- Scripts\CheckCaptcha.js
- App_Start\RouteConfig.cs
- Web.config
Views\Sample\Index.cshtml
@* namespaces needed to access BotDetect members and the CaptchaHelper class *@ @using BotDetect.Web.UI.Mvc; @using AspNetMvc40AjaxCaptchaSampleRazorCSharp.App_Code; @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>BotDetect ASP.NET MVC 4.0 jQuery Ajax CAPTCHA Sample Razor C#< /title> <link href="@Url.Content("~/Style/Sheet.css")" rel="stylesheet" type="text/css" /> <link href="@BotDetect.Web.CaptchaUrls.Absolute.LayoutStyleSheetUrl" rel="stylesheet" type="text/css" /> </head> <body> <h1>BotDetect ASP.NET MVC 4.0 jQuery Ajax CAPTCHA Sample</h1> @using (Html.BeginForm()) { <fieldset> <legend>CAPTCHA Validation Using jQuery Ajax</legend> <div> @Html.Label("CaptchaCode", "Retype the code from the picture:") @{ MvcCaptcha sampleCaptcha = CaptchaHelper.GetSampleCaptcha(); } @Html.Captcha(sampleCaptcha) </div> <div class="actions"> @Html.TextBox("CaptchaCode") <span class="status" id="status">Not checked yet</span> <a href="#" id="check">Check</a> </div> </fieldset> <script src="@Url.Content("~/Scripts/jquery-1.7.1.js")"></script> <script src="@Url.Content("~/Scripts/CheckCaptcha.js")"></script> } </body> </html>
To display Captcha protection on the sample View, we first ensure we can use BotDetect members and the application code by using
the relevant namespaces.
We then use the CaptchaHelper
to create a MvcCaptcha
instance, and add it to the form by calling the Html.Captcha()
Html helper with it.
The jQuery Ajax Captcha validation code is kept in a JavaScript file called CheckCaptcha.js
, which we include at the bottom of the form.
Since we want to show a general case of getting the Captcha validation result with an Ajax call, the form is not submitted with a button, but we add a link which will start Ajax Captcha validation when clicked (as will be shown in client-side code).
Controllers\SampleController.cs
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.Mvc; using BotDetect.Web; using BotDetect.Web.UI.Mvc; namespace AspNetMvc40AjaxCaptchaSampleRazorCSharp.Controllers { public class SampleController : Controller { // // /Sample/Index public ActionResult Index() { return View(); } // // GET: /Sample/CheckCaptcha/ [OutputCache(Location = OutputCacheLocation.None, NoStore = true)] public JsonResult CheckCaptcha(string captchaId, string instanceId, string userInput) { bool ajaxValidationResult = CaptchaControl.AjaxValidate(captchaId, userInput, instanceId); return Json(ajaxValidationResult, JsonRequestBehavior.AllowGet); } } }
To get the Captcha validation result, we call the static Validate()
method from the MvcCaptcha
API. The parameters it takes are:
captchaId
is the identifier of the Captcha instance we passed to theMvcCaptcha
constructor inCaptchaHelper
code.userInput
is the sequence of characters the user retyped from the Captcha image before starting validation.instanceId
is the unique identifier of the Captcha code we are validating, which the calling script reads from the client-side Captcha object.
The validation call is executed within an action returning a JsonResult
, for which we also disabled all caching using the OutputCache
attribute. Caching the result makes no sense since each Captcha code can only be validated once.
It's important to note that this sample only shows how to perform Ajax Captcha validation in an ASP.NET MVC application using jQuery. Depending on how you intend to use Captcha protection, you should also ensure that bots you're trying to block (which mostly don't execute client-side code at all) can't trivially bypass your client-side security measures, as explained in the BotDetect FAQ.
App_Code\CaptchaHelper.cs
using System; using System.Collections.Generic; using System.Linq; using System.Web; using BotDetect.Web.UI.Mvc; namespace AspNetMvc40AjaxCaptchaSampleRazorCSharp.App_Code { 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; } } }
Since there are many properties of the Captcha object you might want to set, we separate MvcCaptcha
instance creation in a class apart from View code. This way we keep the View code short, and can have multiple Captchas in different Views without having to keep Captcha code scattered over each View code.
Each Captcha instance should have a unique ID, which we pass to the MvcCaptcha
constructor (and which is also used in the Captcha validation call in Controller code).
Setting the UserInputClientID
property to the client-side ID of the Captcha code input textbox is necessary to wire-up client-side input and validation functionality.
Scripts\CheckCaptcha.js
$(document).ready(function () { $('#check').click(function checkForm(event) { $('#status').attr('class', 'inProgress'); $('#status').text('Checking...'); // get client-side Captcha object instance var captchaObj = $("#CaptchaCode").get(0).Captcha; // gather data required for Captcha validation var params = {} params.CaptchaId = captchaObj.Id; params.InstanceId = captchaObj.InstanceId; params.UserInput = $("#CaptchaCode").val(); // make asynchronous Captcha validation request $.getJSON('Sample/CheckCaptcha', params, function (result) { if (true === result) { $('#status').attr('class', 'correct'); $('#status').text('Check passed'); } else { $('#status').attr('class', 'incorrect'); $('#status').text('Check failed'); // always change Captcha code if validation fails captchaObj.ReloadImage(); } }); event.preventDefault(); }) });
The Ajax Captcha validation request is made using the $.getJSON()
jQuery function, and goes to the Url of the MVC Controller + Action performing Captcha validation in server-side code.
To get the captchaId
and instanceId
parameters we need for the Captcha validation call, we first get the client-side Captcha object which was automatically added to the Captcha code textbox.
Since we want to keep this sample simple and generic enough to be useful for diverse Ajax Captcha use-cases, we just display the validation result directly on the form. What we need to do in any use-case is reload the Captcha image if validation failed, since each random Captcha code can only be attempted once for security reasons, and the user must be shown a new code.
App_Start\RouteConfig.cs
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Routing; namespace AspNetMvc40AjaxCaptchaSampleRazorCSharp { public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); // BotDetect requests must not be routed routes.IgnoreRoute("{*botdetect}", new { botdetect = @"(.*)BotDetectCaptcha\.ashx" }); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Sample", action = "Index", id = UrlParameter.Optional } ); } } }
We configure ASP.NET Routing to ignore BotDetect requests, since they do not conform to any MVC-related patterns. The regex defining requests to ignore must match the path configured for the BotDetect HttpHandler
registered in web.config
.
Web.config
<?xml version="1.0" encoding="utf-8"?> <!-- For more information on how to configure your ASP.NET application, please visit http://go.microsoft.com/fwlink/?LinkId=169433 --> <configuration> <configSections> <section name="botDetect" requirePermission="false" type="BotDetect.Configuration.BotDetectConfigurationSection, BotDetect"/> </configSections> <appSettings> <add key="webpages:Version" value="2.0.0.0" /> <add key="webpages:Enabled" value="false" /> <add key="PreserveLoginUrl" value="true" /> <add key="ClientValidationEnabled" value="true" /> <add key="UnobtrusiveJavaScriptEnabled" value="true" /> </appSettings> <system.web> <httpRuntime targetFramework="4.5" /> <compilation debug="true" targetFramework="4.5" /> <!-- make sure Session State is enabled --> <pages enableSessionState="true"> <namespaces> <add namespace="System.Web.Helpers" /> <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.Web.WebPages" /> </namespaces> </pages> <!-- configure Session State for BotDetect use --> <sessionState mode="InProc" cookieless="AutoDetect" timeout="20" sessionIDManagerType="BotDetect.Web.CustomSessionIdManager, BotDetect"/> <httpHandlers> <!-- register HttpHandler used for BotDetect Captcha requests --> <add verb="GET" path="BotDetectCaptcha.ashx" type="BotDetect.Web.CaptchaHandler, BotDetect"/> </httpHandlers> </system.web> <system.webServer> <validation validateIntegratedModeConfiguration="false" /> <handlers> <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" /> <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" /> <remove name="ExtensionlessUrlHandler-Integrated-4.0" /> <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET, HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0. 30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0, bitness32" responseBufferLimit="0" /> <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET, HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0. 30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0, bitness64" responseBufferLimit="0" /> <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET, HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers. TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> <!-- 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-4.0.0.0" newVersion="4.0.0.0" /> </dependentAssembly> </assemblyBinding> </runtime> <botDetect> <captchaImage> <helpLink enabled="true" mode="image" /> </captchaImage> </botDetect> </configuration>
To allow the application to use BotDetect Captcha protection, we must enable and configure sessionState
, and register the BotDetect HttpHandler
in both <system.web><httpHandlers>
and <system.webServer><handlers>
configuration sections.
The <dependentAssembly>
entry for System.Web.Mvc
is also needed to make all ASP.NET MVC dependencies referenced by the BotDetect MVC assembly point to the correct ASP.NET MVC version.
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