Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Tom Engan 430 posts 1173 karma points
    Oct 26, 2016 @ 13:48
    Tom Engan
    0

    reCaptcha 2.0 and ContactFormSurfaceController

    My ContactFormSurfaceController works very well in latest Umbraco, and ContactFormSurfaceController.cs look like this (also a model named ContactFormViewModel.cs, a Partial View file named ContactForm, and a Partial View Macro File named ContactForm exists):

    using Neoweb.Models;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Net.Mail;
    using System.Web;
    using System.Web.Mvc;
    using Umbraco.Web.Mvc;
    
    namespace Neoweb.Controllers
    {
        public class ContactFormSurfaceController : SurfaceController
        {
            // GET: ContactFormSurface
            public ActionResult Index()
            {
                return PartialView("ContactForm", new ContactFormViewModel());
            }
    
            [HttpPost]
            public ActionResult ContactFormSubmit(ContactFormViewModel model)
            {
                if (!ModelState.IsValid)
                    return CurrentUmbracoPage();
    
                // Send email
                MailMessage message = new MailMessage();
                message.To.Add("[email protected]");
                message.Subject = "New message";
                message.From = new System.Net.Mail.MailAddress(model.Email, model.Name);
                message.Body = model.Message;
                SmtpClient smtp = new SmtpClient();
                smtp.Send(message);
    
                TempData["success"] = true;
    
                return RedirectToCurrentUmbracoPage();
            }
        }
    } 
    

    But now I want to implement reCAPTCHA 2.0 under the contact form like this (inside the same Fieldset):

    enter image description here

    I tried to implement reCaptcha codes like this direct into SurfaceController, but the reCapthca didn't stop the user - it send the ContactForm anyway, if all field are filled (Name, Email, Message):

    using Neoweb.Models;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Linq;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Net.Mail;
    using System.Web;
    using System.Web.Mvc;
    using Umbraco.Web.Mvc;
    
    namespace Neoweb.Controllers
    {
        public class ContactFormSurfaceController : SurfaceController
        {
            // GET: ContactFormSurface
            public ActionResult Index()
            {
                return PartialView("ContactForm", new ContactFormViewModel());
            }
    
            [HttpPost]
            public ActionResult ContactFormSubmit(ContactFormViewModel model)
            {
    
                //Validate Google recaptcha here
                var response = System.Web.HttpContext.Current.Request["g-recaptcha-response"];
                string secretKey = "xxxxxxxxxxxxxx HIDED xxxxxxxxxxxxxx";
                var client = new WebClient();
                var result = client.DownloadString(string.Format("https://www.google.com/recaptcha/api/siteverify?secret={0}&response={1}", secretKey, response));
                var obj = JObject.Parse(result);
                var status = (bool)obj.SelectToken("success");
    
                if (!ModelState.IsValid || !status)
                    return CurrentUmbracoPage();
    
                // Send email
                MailMessage message = new MailMessage();
                message.To.Add("[email protected]");
                message.Subject = "New message";
                message.From = new System.Net.Mail.MailAddress(model.Email, model.Name);
                message.Body = model.Message;
                SmtpClient smtp = new SmtpClient();
                smtp.Send(message);
    
                TempData["success"] = true;
    
                return RedirectToCurrentUmbracoPage();
            }
        }
    }
    

    Any ideas?

  • Alex Skrypnyk 6132 posts 23951 karma points MVP 7x admin c-trib
    Oct 26, 2016 @ 15:59
    Alex Skrypnyk
    1

    Hi Tom,

    Did you try to debug and look what answer comes from Google API?

    Is this (bool)obj.SelectToken("success") really true?

    We worked on reCAPTCHA 2.0 for umbraco Forms - https://our.umbraco.org/projects/collaboration/recaptcha-field-for-umbraco-forms/

    You can look at source code

    Thanks,

    Alex

  • Tom Engan 430 posts 1173 karma points
    Oct 27, 2016 @ 14:57
    Tom Engan
    0

    Yes, (bool)obj.SelectToken("success") is set to true, so it must be something else.

    Strange that if (!ModelState.IsValid || !status) return CurrentUmbracoPage(); fieldvalidation works fine, but not stop if reCaptcha gives an error (when 'status' is set to false):


    ContactFormViewModel.cs (Model):

    using Newtonsoft.Json;
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.Linq;
    using System.Web;
    
    namespace Neoweb.Models
    {
        public class ContactFormViewModel
        {
            [Required]
            public string Name { get; set; }
            [Required]
            [EmailAddress]
            public string Email { get; set; }
            [Required]
            public string Message { get; set; }
        }
    }
    

    ContactForm.cshtml (Partial View)

    @model Neoweb.Models.ContactFormViewModel
    @if (TempData["success"] == null)
    {
        <div class="well-sm contact-form">
            @using (Html.BeginUmbracoForm<Neoweb.Controllers.ContactFormSurfaceController>("ContactFormSubmit"))
            {
                <fieldset>
                    <legend class="">Kontakt Neoweb</legend>
                    <div class="form-group">
                        <span class="fa fa-user bigicon"></span>
                        @Html.TextBoxFor(m => m.Name, new { @class = "form-control", placeholder = "Fullt navn" })
                        @Html.ValidationMessageFor(m => m.Name, "Navn er påkrevd.")
                    </div>
                    <div class="form-group">
                        <span class="fa fa-envelope-o bigicon"></span>
                        @Html.TextBoxFor(m => m.Email, new { @class = "form-control", placeholder = "E-post" })
                        @Html.ValidationMessageFor(m => m.Email, "E-post adresse er påkrevd.")
                    </div>
                    <div class="form-group">
                        <span class="fa fa-pencil-square-o bigicon"></span>
                        @Html.TextAreaFor(m => m.Message, new { @class = "form-control", placeholder = "Melding", rows = "7" })
                        @Html.ValidationMessageFor(m => m.Message, "Meldingstekst er påkrevd.")
                    </div>
                    <div class="g-recaptcha" data-sitekey="xxxxxxxxxxxxxx HIDED xxxxxxxxxxxxxx"></div>
                    <div class="form-group">
                        <button type="submit" class="btn btn-primary">Send melding</button>
                    </div>
                </fieldset>
            }
        </div>
    }
    else
    {
        <div class="well-sm">
            <p>Takk, du hører snart fra oss</p>
        </div>  
    }
    

    ContactForm.cshtml (Partial View Macro File):

    @inherits Umbraco.Web.Macros.PartialViewMacroPage
    @Html.Action("Index", "ContactFormSurface")
    
  • Alex Skrypnyk 6132 posts 23951 karma points MVP 7x admin c-trib
    Oct 27, 2016 @ 20:52
    Alex Skrypnyk
    0

    Hi Tom,

    Its strange solution but maybe it will help you:

    if (!ModelState.IsValid)
                    return CurrentUmbracoPage();
    
    if (!status)
                    return CurrentUmbracoPage();
    

    Thanks,

    Alex

  • Tom Engan 430 posts 1173 karma points
    Nov 01, 2016 @ 13:05
    Tom Engan
    101

    Both solutions should work, but it didn't. But after I transferred the entire solution over to the webhotel again, it now works also with reCAPTCHA (I didn't test mail server locally on my development machine, therefore probably these solutions have not been identical).

    Now the entire solution is working, and it looks like this:


    ContactFormSurfaceController.cs

    using Neoweb.Models;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Linq;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Net.Mail;
    using System.Web;
    using System.Web.Mvc;
    using Umbraco.Web.Mvc;
    
    namespace Neoweb.Controllers
    {
        public class ContactFormSurfaceController : SurfaceController
        {
            // GET: ContactFormSurface
            public ActionResult Index()
            {
    
                if (TempData["reCaptcha"] == null)
                {
                    ViewBag.MessageToUser = "Kontakt Neoweb";
                }
    
                return PartialView("ContactForm", new ContactFormViewModel());
            }
    
            [HttpPost]
            public ActionResult ContactFormSubmit(ContactFormViewModel model)
            {
    
                //Validate Google recaptcha here
                var response = Request["g-recaptcha-response"];
                string secretKey = "xxxxxxxxxxxxxx HIDED xxxxxxxxxxxxxx";
                var client = new WebClient();
                var result = client.DownloadString(string.Format("https://www.google.com/recaptcha/api/siteverify?secret={0}&response={1}", secretKey, response));
                var obj = JObject.Parse(result);
                var status = (bool)obj.SelectToken("success");
                TempData["reCaptcha"] = status;
    
                if (!ModelState.IsValid)
                {
                    ViewBag.MessageToUser = "Alle felt må utfylles";
                    return CurrentUmbracoPage();
                }
    
                if (!status)
                {
                    // ViewBag.MessageToUser = status ? "reCaptcha validation success" : "reCaptcha validation failed";
                    ViewBag.MessageToUser = "Kryss av for ikke robot";
                    return CurrentUmbracoPage();
                }
                else
                {
                    // Send email
                    MailMessage message = new MailMessage();
                    message.To.Add("[email protected]");
                    message.Subject = "New message";
                    message.From = new System.Net.Mail.MailAddress(model.Email, model.Name);
                    message.Body = model.Message;
                    SmtpClient smtp = new SmtpClient();
                    smtp.Send(message);
    
                    TempData["success"] = true;
    
                    return RedirectToCurrentUmbracoPage();
                }    
            }
        }
    }
    

    ContactForm.cshtml

    @model Neoweb.Models.ContactFormViewModel
    @if (TempData["success"] == null)
    {
        <div class="well-sm contact-form">
            @using (Html.BeginUmbracoForm<Neoweb.Controllers.ContactFormSurfaceController>("ContactFormSubmit"))
            {
                <fieldset>
    
                    <legend class="">@ViewBag.MessageToUser</legend>
    
                    <div class="form-group">
                        <span class="fa fa-user bigicon"></span>
                        @Html.TextBoxFor(m => m.Name, new { @class = "form-control", placeholder = "Fullt navn" })
                        @Html.ValidationMessageFor(m => m.Name, "Navn er påkrevd.")
                    </div>
                    <div class="form-group">
                        <span class="fa fa-envelope-o bigicon"></span>
                        @Html.TextBoxFor(m => m.Email, new { @class = "form-control", placeholder = "E-post" })
                        @Html.ValidationMessageFor(m => m.Email, "E-post adresse er påkrevd.")
                    </div>
                    <div class="form-group">
                        <span class="fa fa-pencil-square-o bigicon"></span>
                        @Html.TextAreaFor(m => m.Message, new { @class = "form-control", placeholder = "Melding", rows = "7" })
                        @Html.ValidationMessageFor(m => m.Message, "Meldingstekst er påkrevd.")
                    </div>
                    <div class="g-recaptcha" data-sitekey="xxxxxxxxxxxxxx HIDED xxxxxxxxxxxxxx"></div>
                    <div class="form-group">
                        <button type="submit" class="btn btn-primary">Send melding</button>
                    </div>
                </fieldset>
            }
        </div>
    }
    else
    {
        <div class="well-sm">
            <p>Takk, du hører snart fra oss</p>
        </div>
    }
    

    ContactFormViewModel.cs (Model):

    using Newtonsoft.Json;
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.Linq;
    using System.Web;
    
    namespace Neoweb.Models
    {
        public class ContactFormViewModel
        {
            [Required]
            public string Name { get; set; }
            [Required]
            [EmailAddress]
            public string Email { get; set; }
            [Required]
            public string Message { get; set; }
        }
    }
    

    ContactForm.cshtml (Partial View Macro File):

    @inherits Umbraco.Web.Macros.PartialViewMacroPage
    @Html.Action("Index", "ContactFormSurface")
    

    Everything is now OK, but ideas if the solution can be improved further will be appreciated

Please Sign in or register to post replies

Write your reply to:

Draft