Skip to content

Using PoliteCaptcha with ReCaptcha in an Ajax POST

Jérémie Bertrand edited this page Mar 22, 2014 · 3 revisions

PoliteCaptch is conceived to be used with a traditional POST request, not an Ajax one. But it is possible with only some simple steps:

In your controller, add the ValidateSpamPrevention attribute to actions that handle forms and throw an exception if the PoliteCaptcha fail. You could also use a Json response if you want to be more precise on the failure cause.

[HttpPost, ValidateSpamPrevention]
public ActionResult RegisterMember(RegisterMemberRequest request)
{
    if (ModelState.IsValid)
    {
        // ...
    }
    else
    {
        if (ModelState.ContainsKey("PoliteCaptcha"))
        {
            throw new Exception("PoliteCaptcha failed");
        }
    }
}

In your ajax form, don't invoke the SpamPreventionFields() HTML helper but add a div with an id:

@using (Ajax.BeginForm(... new AjaxOptions
{
    OnFailure = "MyAjaxFormFailure"
}))
{
    @Html.EditorForModel()
    <div id="ReCaptcha">
    </div>
    <input type="submit" value="Submit" />
}

And in the script section or in a javascript file define the MyAjaxFormFailure method:

function MyAjaxFormFailure {
    Recaptcha.create("6LehOM0SAAAAAPgsjOy-6_grqy1JiB_W_jJa_aCw", // ReCaptcha public key
                 "ReCaptcha",
                 {
                     theme: "blackglass", // a theme, default is 'red'
                     callback: Recaptcha.focus_response_field // give the focus to the ReCaptcha field
                 });
}

More info on the Recaptcha.create method in the documentation of ReCaptcha AJAX API.

And don't forget to invoke the SpamPreventionSCript() HTML helper in your view's scripts section (or in the layout)

@section PostFooter {
    <script src="@Url.Content("~/Scripts/jquery-1.6.2.min.js")"></script>
    <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
    @Html.SpamPreventionScript()
}