Rolling your own ASP.Net MVC reCAPTCHA Helper

Rolling your own ASP.Net MVC reCAPTCHA Helper

I needed to add a CAPTCHA to a ASP.Net MVC web form recently. Since the ASP.Net Web Helpers Library is not compatible with ASP.NET MVC, I searched the web for another solution. I did find MvcReCaptcha, but unfortunately the projects were a little out of date.

image.png

Rolling my own

I found a great solution from Chase Florell on StackOverflow. However it was in VB, so I’ve decided to share the C# version with you.

First, download the reCAPTCHA .NET Library and add the Recaptcha.dll file to your project references.

image.png

Next, in your ASP.Net MVC project, create a new folder called Helpers. In this folder create a class and call it ReCaptchaHelper.cs

image.png

Create a static method in the class called ReCAPTCHA, the code listing for the class looks as follows:

public class ReCaptchaHelper
{
    public static MvcHtmlString ReCAPTCHA()
    {
        MvcHtmlString captchaHtml;

        using (Recaptcha.RecaptchaControl captchaControl = 

           new Recaptcha.RecaptchaControl { 
            ID = "ReCaptcha", 
            Theme = "Clean", 
            PublicKey = "--YourPublicKey--", 
            PrivateKey = "--YourPrivateKey--" })
        {
            using (HtmlTextWriter htmlWriter = 

             new HtmlTextWriter(new StringWriter()))
            {
                captchaControl.RenderControl(htmlWriter);
                captchaHtml = 

                MvcHtmlString.Create(htmlWriter.InnerWriter.ToString());
            }
        }
        return captchaHtml;
    }
}

You need to add a Validation folder next and create a ValidateCaptchaAttribute.cs class in the folder. image.png

The code listing for the class is:

public class ValidateCaptchaAttribute : ActionFilterAttribute
{
    string CHALLENGE_FIELD_KEY = "recaptcha_challenge_field";
    string RESPONSE_FIELD_KEY = "recaptcha_response_field";

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext.HttpContext.Request.Form[CHALLENGE_FIELD_KEY] == null)
        {
            filterContext.ActionParameters["CaptchaIsValid"] = true;
            return;
        }

        var captchaChallengeValue = 

          filterContext.HttpContext.Request.Form[CHALLENGE_FIELD_KEY];
        var captchaResponseValue = 

          filterContext.HttpContext.Request.Form[RESPONSE_FIELD_KEY];

        var captchaValidator = new Recaptcha.RecaptchaValidator
        {
            PrivateKey = "--YourPrivateKey--",
            RemoteIP = filterContext.HttpContext.Request.UserHostAddress,
            Challenge = captchaChallengeValue,
            Response = captchaResponseValue
        };

        var recaptchaResponse = captchaValidator.Validate();
        filterContext.ActionParameters["CaptchaIsValid"] = 

            recaptchaResponse.IsValid;

        base.OnActionExecuting(filterContext);
    }
}

To add a ReCAPTCHA to your view you simply need to use the ReCaptchaHelper:

@using (Html.BeginForm())
{
    @ReCaptchaHelper.ReCAPTCHA()
    <input type="submit" value="Go" />
}

You would need to add a @using to the top of your view in order for the helper to work e.g.:

@using YourWebsiteNameSpace.Helpers

Finally, in the Controller action for the view, you need to add the validation attribute:

[HttpPost]
[Validation.ValidateCaptcha()]
public ActionResult Index(bool captchaIsValid)
{
    if (!captchaIsValid)
    {
        ModelState.AddModelError("recaptcha", "*");
    }

    return View();
}

When you run your project, you should now see a reCaptcha in your view, and when you post the form, if the captcha is valid, the captchaIsValid parameter should return true.

image.png

As easy as that and very handy!