0

I'm working on a Kentico app V12 (after the same code will be deployed to other installations from 12 to 7) and I added a new form control. In my case the control is for the Google Recaptcha V3 token (so I don't need to save the value), so these are my steps:

  • I added the new form control through the Kentico interface
  • I added a new field in one form to test the functionality
  • I added the Javascript part to manage the recaptcha validation

Actually I'm able to manage all the flow on the client side, my goal now it's validate the token before saving the data, so I added this code on my ascx file

public partial class CMSModules_ReCAPTCHA : FormEngineUserControl
{

    private static string GOOGLE_RECAPTCHA_LIBRARY_URL = "https://www.google.com/recaptcha/api.js";

    public override bool IsValid()
    {
        return this.Validate();
    }

    public override object Value
    {
        get
        {
            // How can I get the value?
        }
        set { }
    }

    private bool Validate()
    {
        // Here's the code to validate the token
    }
}

If I send the form I can see on the inspector that the token is sent, but how can I get that value on my ascx file and get an error message if the validation is not successful? I tried with CMS.Helpers.ValidationHelper.GetString(Form.GetFieldValue("reCAPTCHA")) but it's not working. reCAPTCHA it's the field's name, the value is sent as g-recaptcha-response.

stuzzo
  • 1,056
  • 1
  • 15
  • 36

1 Answers1

1

So the way we have handled this is to add in a HiddenField control on the front end file (.ascx) that HiddenField gets populated by the javascript that you are running to work with the standard recaptcha stuff (as you mention). Then on postback of the form, that HiddenField has the token value that your Value property can use.

On the .ascx of the formcontrol

<asp:HiddenField runat="server" ID="recaptchaToken" ClientIDMode="Static" />

Then on your .ascx.cs file of the formcontrol

public override object Value
{
    get
    {
        return recaptchaToken.Value;
    }
    set
    {
        recaptchaToken.Value = (string)value;
    }
}

That way it should be there on the Postback of the form that you have the form control on.

Remember your JavaScript needs to populate the value as well. Like:

document.getElementById('recaptchaToken').value = token; //the one from Google

You may also have to handle the validation. For that we override the IsValid member and call out to Google for Validation with the token. Down and dirty version would look like:

public override bool IsValid()
{
    if (Value == null || String.IsNullOrEmpty(Value.ToString()))
        return false;

    var tokenResponse = Value.ToString();

    // Clear for next time around
    Value = "";

    return ReCaptchaCheckPassed(GoogleSecretKey, tokenResponse);
}

public static bool ReCaptchaCheckPassed(string GoogleSecretKey, string RecaptchaResponse)
{
    HttpClient httpClient = new HttpClient();

    var res = httpClient.GetAsync($"https://www.google.com/recaptcha/api/siteverify?secret={googleSecretKey}&response={RecaptchaResponse}").Result;

    if (res.StatusCode != HttpStatusCode.OK)
        return false;

    string JSONres = res.Content.ReadAsStringAsync().Result;

    dynamic JSONdata = JObject.Parse(JSONres);

    if (JSONdata.success != "true")
        return false;

    return true;
}
Mcbeev
  • 1,519
  • 9
  • 9
  • Your suggest is working, but the all validation is failing (while the field validation is ok) after I added this field. Maybe Kentico thinks that field as not mapped or something like that? I can't find any error message, but the submit failed and Kentico shows the message "please fill all the required fields". – stuzzo Mar 02 '21 at 17:33
  • 1
    Ah sorry, thought you had that part. We override the IsValid call and talk to the Google service for the Validation. I'll edit the answer above. – Mcbeev Mar 02 '21 at 18:04