Error Integrating Google reCAPTCHA with Sitecore Forms

As of now we all know that Sitecore Forms comes with a lot of powerful and excellent features OOTB. And for the few important features which are missing OOTB on the Sitecore Experience Platform, we have Sitecore Forms Extension module published by BART VERDONCK and ERHAN KORKUT.

Sitecore Forms Extensions bring a lot of cool features to the platform along with integration with Google reCAPTCHA. Though Captcha should have been a must to have field for a module like Sitecore Forms which meant to be used by digital marketing specialists and content editor with minimal or zero IT involvement, especially when we talk about designing the user inputs form on the fly for a website. But that is where we have Sitecore Community Contributors as super powers.

We had a requirement to integrate Google reCAPTCHA on Forms and being a lazy developer rather developing a custom field for my project, as any other Sitecore module installation I installed Sitecore Form Extension. We get reCAPTCHA as a drag and drop field and with little configuration about private/secure key you are good to go integrating it with your forms. We did the same everything went pretty smooth on local development and Dev environment.

Then we deployed it on Staging environment and we faced an issue. While trying to submit the form, we were unable to and getting the below exception:

Unexpected character encountered while parsing value: <. Path ”, line 0, position 0.

When checked the log files we see the exception below:

Exception: Newtonsoft.Json.JsonReaderException
Message: Unexpected character encountered while parsing value: <. Path '', line 0, position 0.
Source: Newtonsoft.Json
   at Newtonsoft.Json.JsonTextReader.ParseValue()
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ReadForType(JsonReader reader, JsonContract contract, Boolean hasConverter)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
   at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)
   at Feature.FormsExtensions.Business.ReCaptcha.ReCaptchaService.<>c__DisplayClass3_0.b__0()
   at System.Threading.Tasks.Task`1.InnerInvoke()
   at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at Feature.FormsExtensions.Business.ReCaptcha.ReCaptchaService.d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at Feature.FormsExtensions.Business.ReCaptcha.AsyncHelpers.RunSync[T](Func`1 func)
   at Feature.FormsExtensions.Business.ReCaptcha.ReCaptchaService.VerifySync(String response)
   at Feature.FormsExtensions.Fields.ReCaptcha.ReCaptchaValidationAttribute.IsValid(Object value)
   at System.ComponentModel.DataAnnotations.ValidationAttribute.IsValid(Object value, ValidationContext validationContext)
   at System.ComponentModel.DataAnnotations.ValidationAttribute.GetValidationResult(Object value, ValidationContext validationContext)
   at System.Web.Mvc.DataAnnotationsModelValidator.Validate(Object container)
   at System.Web.Mvc.ModelValidator.CompositeModelValidator.d__1.MoveNext()
   at System.Web.Mvc.DefaultModelBinder.OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext)
   at System.Web.Mvc.DefaultModelBinder.BindComplexElementalModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Object model)
   at System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
   at Sitecore.ExperienceForms.Mvc.Controllers.ModelBinders.FormDataModelBinder.BindFields(ControllerContext controllerContext, ModelBindingContext bindingContext, Guid formId)
   at Sitecore.ExperienceForms.Mvc.Controllers.ModelBinders.FormDataModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
   at System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor)
   at System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.b__19(AsyncCallback asyncCallback, Object asyncState)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout)
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.BeginInvokeAction(ControllerContext controllerContext, String actionName, AsyncCallback callback, Object state)
   at System.Web.Mvc.Controller.b__1c(AsyncCallback asyncCallback, Object asyncState, ExecuteCoreState innerState)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallBeginDelegate(AsyncCallback callback, Object callbackState)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout)
   at System.Web.Mvc.Controller.BeginExecuteCore(AsyncCallback callback, Object state)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout)
   at System.Web.Mvc.Controller.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state)
   at System.Web.Mvc.MvcHandler.b__4(AsyncCallback asyncCallback, Object asyncState, ProcessRequestState innerState)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallBeginDelegate(AsyncCallback callback, Object callbackState)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout)
   at System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state)
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step)
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

Solution:

This was an easy one. We observed that reCAPTCHA calls an API (https://www.google.com/recaptcha/api) which was blocked on the environment by firewall. Unblocking the API URL fixed the issue.

Hope this helps.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Powered by WordPress.com.

Up ↑

%d bloggers like this: