Jasinski Technical Wiki

Navigation

Home Page
Index
All Pages

Quick Search
»
Advanced Search »

Contributor Links

Create a new Page
Administration
File Management
Login/Logout
Your Profile

Other Wiki Sections

Software

PoweredBy

Page History: reCaptcha Implementation in MVC3 - ASP.NET MVC

Compare Page Revisions



« Older Revision - Back to Page History - Current Revision


Page Revision: Fri, Aug 26, 2011, 10:12 AM


Overview

This article outlines how to implement the reCaptcha control in an ASP.NET MVC3/Razor website. The reCaptcha control is a free CAPTCHA implementation available here.

Non-Reusable Code

The following steps will have to be taken for each instance of the reCaptcha control required. It assumes you have already implemented steps in the Reusable Code section below.

View Model

For any view that requires the reCaptcha control, have the view model inherit from the Recaptchable base class.

View

In the code for the view, include the following code where you want the reCaptcha control to appear.

@Html.Partial("Recaptcha")
@Html.ValidationMessageFor(m => m.Recaptcha)

Reusable Code

Web.Config

In your web.config, add the following settings to your /configuration/appSettings section.

<!-- reCaptcha-->
<add key="Recaptcha.PublicKey"  value="your-public-key" />
<add key="Recaptcha.PrivateKey" value="your-private-key" />
<add key="Recaptcha.ValidationUrl" value="http://www.google.com/recaptcha/api/verify" />

Shared View

To your /Views/Shared/ folder, create a new view called Recaptcha.cshtml and add the following code to it.

@using System.Configuration
@{
    var key = ConfigurationManager.AppSettings["Recaptcha.PublicKey"];
}
<script type="text/javascript"
    src="https://www.google.com/recaptcha/api/challenge?k=@(key)">
</script>
<noscript>
    <iframe src="https://www.google.com/recaptcha/api/noscript?k=@(key)"
        height="300" width="500" frameborder="0"></iframe><br />
    <textarea name="recaptcha_challenge_field" rows="3" cols="40">
    </textarea>
    <input type="hidden" name="recaptcha_response_field" 
        value="manual_challenge" />
</noscript>

WebRequestHelper Class

Create a new class called WebRequestHelper.cs and add the following code to it.

using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Web;

public class WebRequestHelper
{
    public enum RequestMethod
    {
        Post,
        Get
    }

    readonly WebRequest _request;
    readonly List<string> _queryData;

    public WebRequestHelper(string url)
    {
        _request = WebRequest.Create(url);
        //_request.Method = "POST";
        Method = RequestMethod.Post;
        _queryData = new List<string>();
    }

    /// <summary>
    /// Defaults to POST
    /// </summary>
    public RequestMethod Method
    {
        get { return (RequestMethod)Enum.Parse(typeof (RequestMethod), _request.Method); }
        set { _request.Method = value.ToString(); }
    }
    public void Add(string key, string value)
    {
        _queryData.Add(String.Format("{0}={1}", key, HttpUtility.UrlEncode(value)));
    }

    public string GetResponse()
    {
        // Set the encoding type
        _request.ContentType = "application/x-www-form-urlencoded";

        // Build a string containing all the parameters
        //var parameters = String.Join("&", (String[])_queryData.ToArray(typeof(string)));
        var parameters = string.Join("&", _queryData);
        _request.ContentLength = parameters.Length;

        // We write the parameters into the request
        var sw = new StreamWriter(_request.GetRequestStream());
        sw.Write(parameters);
        sw.Close();

        // Execute the query
        var response = _request.GetResponse();
        var sr = new StreamReader(response.GetResponseStream());
        return sr.ReadToEnd();
    }

}

Recaptchable Base Class

Create a new class called Recaptchable.cs and add the following code to it.

using System.ComponentModel.DataAnnotations;
using System.Configuration;
using System.Web;

public abstract class Recaptchable
{
    [CustomValidation(typeof(RecaptchaValidator), "Validate")]
    public Recaptchable Recaptcha 
    { 
        get { return this; }
    }

    public string recaptcha_challenge_field { get; set; }
    public string recaptcha_response_field { get; set; }

    public static class RecaptchaValidator
    {
        public static ValidationResult Validate(Recaptchable recaptcha) 
        {
            // In the event the RECAPTCHA_CHALLENGE_FIELD is null, we assume it is because
            // the recaptcha control is not displayed on the page; we therefore return
            // a successful validation.
            if (recaptcha.recaptcha_challenge_field == null)
                return ValidationResult.Success;

            var url = ConfigurationManager.AppSettings["Recaptcha.ValidationUrl"];
            var privateKey = ConfigurationManager.AppSettings["Recaptcha.PrivateKey"];
            var remoteIp = HttpContext.Current.Request.UserHostAddress;

            var request = new WebRequestHelper(url);
            request.Add("privatekey", privateKey);
            request.Add("remoteip", remoteIp);
            request.Add("challenge", recaptcha.recaptcha_challenge_field);
            request.Add("response", recaptcha.recaptcha_response_field);

            var items = (request.GetResponse() + "\n").Split('\n');

            return items[0] == "true" ? 
                ValidationResult.Success : 
                new ValidationResult("You did not type the verification word correctly.");
        }
    }

}

ScrewTurn Wiki version 3.0.1.400. Some of the icons created by FamFamFam. Except where noted, all contents Copyright © 1999-2024, Patrick Jasinski.