Adding Google reCAPTCHA widget to Form Pages of ASP.NET MVC Application For Protecting Them From Spam And Abuse.

Step 1: Get the Google reCAPTCHA widget Site key & Secret key

Go to Google reCAPTCHA Admin Page and get the Site key & Secret key for you web application (domain).

Step 2: Existing Form Page where we want to integrate Google reCAPTCHA

ContactUsSubmissionModel.cs – Contact Us Submission Model

namespace SampleApplication.Models
{
    public class ContactUsSubmissionModel
    {
        public string Name { get; set; }
        public string Email { get; set; }
    }
}

HomeController.cs: Home Controller with Contact & Submit action methods

using Newtonsoft.Json;
using SampleApplication.Models;
using SampleApplication.ProcessUtility;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Net;
using System.Text;
using System.Web.Mvc;

namespace SampleApplication.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Contact()
        {
            ViewBag.Message = "Your contact page.";

            return View();
        }

        [HttpPost]
        public JsonResult Submit(ContactUsSubmissionModel model)
        {
            // Form Submission logic

            return this.Json(new { Success = true });
        }
    }
}

Contact.cshtml: View containing Contact Us Form

@{
    ViewBag.Title = "Contact Us Page";
}

@section Scripts{
    @Scripts.Render("~/Scripts/contactus/contactus.js")
}

<div class="row">
    <div class="col-md-10 col-md-offset-1">
        <h1>Contact Us Page</h1>
    </div>
    <div class="col-md-10 col-md-offset-1">
        <h2>Please fill the form</h2>
    </div>
</div>
<div class="row">
    <form role="form" method="POST" id="contact" class="contact-form">
        <div class="col-md-10 col-md-offset-1">
            <div class="col-md-12" style="padding:10px;">
                <p class="allcaps">Name</p>
                <input type="text" name="Name" id="Name" />
            </div>
            <div class="col-md-12" style="padding:10px;">
                <p class="allcaps">Email</p>
                <input type="text" name="Email" id="Email" />
            </div>
            <div class="col-md-12" style="padding:10px;">
                <a data-submiturl="@Url.Action("Submit", "Home")" href="#" id="Submit" class="btn btn-default">Send</a>
            </div>
        </div>
    </form>
</div>

contactus.js: JavaScript code for handling “submit” button click.

var ContactUs = {
    init: function () {
        $(document).on("click", "#Submit", ContactUs.submit);
    },

    submit: function (event) {
        event.preventDefault();
        ContactUs.submitForm();
    },

    submitForm: function () {
        $.ajax({
            type: "POST",
            data: $('#contact').serialize(),
            url: $('#Submit').data().submiturl,
            success: function (response) {
                if (response.Success) {
                    $("#Name").val('');
                    $("#Email").val('');
                }
                else {
                    alert("Error Occurred. Please try again.");
                }
            },
            error: function () {
              // Error handling.
            },
        });
    }
};

$(function () {
    ContactUs.init();
});

Step 3: Adding Google reCAPTCHA widget to Form Page of ASP.NET MVC Application

Application Architecture:

Application With ReCaptcha

Contact.cshtml changes:

Add reference of https://www.google.com/recaptcha/api.js JS to Contact.cshtml.  Add recaptcha and recaptchaMessage Divs  to Contact.cshtml as shown in below code. Do, remember to replace data-sitekey value with one that you have got in Step 1. recaptchaMessage div is used to show reCAPTCHA error message in case of failure.

Google reCaptcha

Contact.cshtml changes are highlighted in the below code.

@{
    ViewBag.Title = "Contact Us Page";
}

@section Scripts{
    <script src="https://www.google.com/recaptcha/api.js" async defer></script>
    @Scripts.Render("~/Scripts/contactus/contactus.js")
}

<div class="row">
    <div class="col-md-10 col-md-offset-1">
        <h1>Contact Us Page</h1>
    </div>
    <div class="col-md-10 col-md-offset-1">
        <h2>Please fill the form</h2>
    </div>
</div>
<div class="row">
    <form role="form" method="POST" id="contact" class="contact-form">
        <div class="col-md-10 col-md-offset-1">
            <div class="col-md-12" style="padding:10px;">
                <p class="allcaps">Name</p>
                <input type="text" name="Name" id="Name" />
            </div>
            <div class="col-md-12" style="padding:10px;">
                <p class="allcaps">Email</p>
                <input type="text" name="Email" id="Email" />
            </div>
            <div id='recaptcha' class="col-md-12 g-recaptcha" style="padding:10px;"
                 data-sitekey="xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
                 data-callback="ContactUs.reCaptchaCallback">
            </div>
            <div id="recaptchaMessage" data-verifyrecaptchatokenurl="@Url.Action("VerifyReCaptchaToken", "Home")" style="display:none;padding:10px;color:red;font-weight:bold;" class="error">You need to verify reCAPTCHA.</div>
            <div class="col-md-12" style="padding:10px;">
                <a data-submiturl="@Url.Action("Submit", "Home")" href="#" id="Submit" class="btn btn-default">Send</a>
            </div>
        </div>
    </form>
</div>

contactus.js changes:

contactus.js is modified to include reCAPTCHA client side verification logic and a ajax call to perform reCAPTCHA server side verification. Also, grecaptcha.reset() is called to reset the reCAPTCHA widget after the form submission.

contactus.js changes are highlighted in the below code.

var ContactUs = {
    init: function () {
        $(document).on("click", "#Submit", ContactUs.submit);
    },

    submit: function (event) {
        event.preventDefault();

        // reCAPTCHA - Client side verification
        if (grecaptcha.getResponse().length == 0) {
            $("#recaptchaMessage").show();
            return;
        }

        // reCAPTCHA - Server-side verification and if verification passes then form submission.
        $.ajax({
            type: "POST",
            data: { 'token': grecaptcha.getResponse() },
            url: $('#recaptchaMessage').data().verifyrecaptchatokenurl,
            success: function (response) {
                if (response.Success) {
                    $("#recaptchaMessage").hide();
                    ContactUs.submitForm();
                }
            },
            error: function () {
                $("#recaptchaMessage").show();
            },
        });
    },

    // reCAPTCHA - Callback function.
    reCaptchaCallback: function (token) {
        if (token.length == 0) {
            $("#recaptchaMessage").show();
        }
        else {
            $("#recaptchaMessage").hide();
        }
    },

    submitForm: function () {
        $.ajax({
            type: "POST",
            data: $('#contact').serialize(),
            url: $('#Submit').data().submiturl,
            success: function (response) {
                // reCAPTCHA - Reset after submission.
                grecaptcha.reset();

                if (response.Success) {
                    $("#Name").val('');
                    $("#Email").val('');
                }
                else {
                    alert("Error Occurred. Please try again.");
                }
            },
            error: function () {
                // Error Handling.

                // reCAPTCHA - Reset in case of failure.
                grecaptcha.reset();
            },
        });
    }
};

$(function () {
    ContactUs.init();
});

HomeController.cs changes:

VerifyReCaptchaToken action method is added to verify reCAPTCHA  user response token on the server side. Do, remember to replace secret value with one that you have got in Step 1. 

using Newtonsoft.Json;
using SampleApplication.Models;
using SampleApplication.ProcessUtility;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Net;
using System.Text;
using System.Web.Mvc;

namespace SampleApplication.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Contact()
        {
            ViewBag.Message = "Your contact page.";

            return View();
        }

        [HttpPost]
        public JsonResult Submit(ContactUsSubmissionModel model)
        {
            // Form Submission logic

            return this.Json(new { Success = true });
        }

        [HttpPost]
        public JsonResult VerifyReCaptchaToken(string token)
        {
            var success = false;

            using (var client = new WebClient())
            {
                var requestData = new NameValueCollection();
                // Replace secret value with one that you have got in Step 1.
                requestData.Add("secret", "yyyyyyyyyyyyyyyyyyyyyyyyyyyy");
                requestData.Add("response", token);
                var responseBytes = client.UploadValues("https://www.google.com/recaptcha/api/siteverify", "POST", requestData);
                string responseBody = Encoding.UTF8.GetString(responseBytes);
                var response = JsonConvert.DeserializeObject<ReCaptchaValidationResponse>(responseBody);
                success = response.Success;
            }

            return this.Json(new { Success = success });
        }
    }
}

Result:

reCaptcha In Action

That’s it….

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *