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:
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.
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:
That’s it….
.NET Professional | Microsoft Certified Professional | DZone’s Most Valuable Blogger | Web Developer | Author | Blogger
Doctorate in Computer Science and Engineering
Microsoft Certified Professional (MCP) with over 12+ years of software industry experience including development, implementation & deployment of applications in the .NET framework
Experienced and skilled Agile Developer with a strong record of excellent teamwork, successful coding & project management. Specialises in problem identification and proposal of alternative solutions. Provided knowledge and individual mentoring to team members as needed
Among top 3% overall in terms of contribution on Stack Overflow (~2.3 million people reached my posts). Part of the top 1% Stack Overflow answerers in ASP.NET technology.
DZone’s Most Valuable Blogger (MVB)
Created and actively maintain the TechCartNow.com tech blog while also editing, writing, and researching topics for publication.
Excellent skills in Application Development using C#/Vb.Net, .NET Framework, ASP.NET, MVC, ADO.NET, WCF, WPF, Web API, SQL Server, jQuery, Angular, React, BackboneJS