自定义窗体提交验证

营销和活动注册表单中的客户端验证有助于确保客户提交的数据的有效性。 但是,在某些情况下,您可能需要更复杂的验证。 例如,您可能需要将提交的数据与系统中已存在的数据进行比较。 为了便于进行复杂的验证,本文详细介绍了如何构建自定义插件来验证后端提交的数据并触发额外的数据处理逻辑。

创建插件

备注

此自定义插件示例展示了如何为 reCAPTCHA 密钥构建后端验证。 它可以作为验证流程的灵感来源。 如果您想将 reCAPTCHA 集成到您的表单中,您可以使用预构建的插件,并 按照本指南进行操作

为插件创建 Visual Studio 项目

  1. 打开 Visual Studio,使用 .NET Framework 4.6.2 创建一个新的类库项目。
  2. 解决方案资源管理器中,选择管理 NuGet 包,安装 Microsoft.CrmSdk.CoreAssemblies

创建插件类

  1. Class1.cs 重命名为 CustomValidationPlugin.cs

  2. 让 CustomValidationPlugin 类从 IPlugin 接口继承,并添加 Execute 方法。

    public class CustomValidationPlugin : IPlugin
    {
       public void Execute(IServiceProvider serviceProvider)
       {
    
       }
    }
    
  3. 若要检索上下文和跟踪服务,请将以下代码添加到 execute 方法中。

    public void Execute(IServiceProvider serviceProvider)
    {
       // get tracing service
       ITracingService tracingService =
       (ITracingService)serviceProvider.GetService(typeof(ITracingService));
    
       // get plugin execution context
       IPluginExecutionContext context = (IPluginExecutionContext)
       serviceProvider.GetService(typeof(IPluginExecutionContext));
    }
    
  4. 添加此代码来检索窗体提交参数字符串。 它是一个 JSON 编码的字符串,表示用户在窗体中提交的字段。 此过程检索字符串并使用反序列化帮助程序方法和稍后定义的 FormSubmissionRequest 类对其进行反序列化。 此代码检查 fields 数组是否包含 g-recaptcha-response 的键。 如果未找到 reCAPTCHA 密钥,则会返回跳过验证,因为正在处理的表单不包含 recaptcha 元素。

    var requestString = (string)context.InputParameters["msdynmkt_formsubmissionrequest"];
    var requestObject = Deserialize<FormSubmissionRequest>(requestString);
    if (!requestObject.Fields.TryGetValue("g-recaptcha-response", out string recaptchaToken))
    {
       tracingService.Trace("g-recaptcha-response was not present in form submission");
       return;
    }
    
  5. 如果 g-recaptcha-token 值为 null 或空,则添加以下代码以返回。

    if (String.IsNullOrEmpty(recaptchaToken))
    {
       tracingService.Trace($"g-recaptcha-response value not found");
       return;
    }
    
  6. 添加以下代码以根据 Google API 验证 Google captcha 令牌。

    string url = "https://www.google.com/recaptcha/api/siteverify";
    using (HttpClient client = new HttpClient())
    {
       var content = new FormUrlEncodedContent(new Dictionary<string, string>
       {
          {"secret", "your_secret_key"},
          {"response", recaptchaToken}
       });
    
       try
       {
          var response = client.PostAsync(url, content).Result;
          if (!response.IsSuccessStatusCode)
          {
             tracingService.Trace($"Request Failed: ({response.StatusCode}){response.Content}");
             return;
          }
    
          var responseString = response.Content.ReadAsStringAsync().Result;
    
          gRecaptchaResponse = Deserialize<GRecaptchaResponse>(responseString);
    
          var resp = new ValidateFormSubmissionResponse()
          {
             IsValid = isValid,
             ValidationOnlyFields = new List<string>() { "g-recaptcha-response" }
          };
          context.OutputParameters["msdynmkt_validationresponse"] = Serialize(resp);
        }
        catch (Exception e)
        {
           tracingService.Trace($"{e.Message}");
        }
    }
    

    首先,将定义 URL,然后将创建 HttpClient 实例。 将创建 FormUrlEncodedContent 对象,其中包含之前步骤中检索到的 recaptchaToken 和 Google 提供的密钥。 然后,发送 POST 请求,并检查状态代码,如果不成功,则返回。 如果成功,将使用反序列化助手方法和之后定义的 GRecaptchaResponse 反序列化响应。 然后,将创建一个新的 ValidateFormSubmissionResponse 对象,对其进行序列化,并将其设置为输出参数 msdynmkt_validationresponse 的值,这是它用来接受或拒绝提交的一项 Microsoft 服务。 将字符串 g-recaptcha-response 添加到 ValidationOnlyFields 列表中会在用户界面中的表单提交中隐藏此字段。

  7. 添加以下代码来定义序列化和反序列化助手方法。

    private T Deserialize<T>(string jsonString)
    {
       serializer = new DataContractJsonSerializer(typeof(T));
       T result;
       using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(jsonString)))
       {
          result = (T)serializer.ReadObject(stream);
       }
       return result;
    }
    
    private string Serialize<T>(T obj)
    {
        string result;
        serializer = new DataContractJsonSerializer(typeof(T));
        using (MemoryStream memoryStream = new MemoryStream())
        {
           serializer.WriteObject(memoryStream, obj);
           result = Encoding.Default.GetString(memoryStream.ToArray());
        }
        return result;
    }
    
  8. 添加以下代码以定义序列化和反序列化 JSON 字符串对象所需的类。

    public class FormSubmissionRequest
     {
         public Dictionary<string, string> Fields { get; set; }
     }
    
     public class GRecaptchaResponse
     {
         public bool success { get; set; }
     }
    
     public class ValidateFormSubmissionResponse
     {
         public bool IsValid { get; set; }
         public List<string> ValidationOnlyFields { get; set; }
     }
    

签署和构建插件

  1. 右键单击项目,在解决方案资源管理器中选择属性
  2. 选择签名选项卡,然后选中为程序集签名复选框。
  3. 选择<New...>
  4. 输入密钥文件名称,取消选择使用密码保护我的密钥文件
  5. 生成项目。
  6. 您可以在 \bin\Debug 中找到插件程序集 CustomValidationPlugin.dll

注册插件

  1. 打开 PluginRegistration.exe
  2. 选择创建新连接
  3. 选择Office 365
  4. 选择登录
  5. 选择注册,然后选择注册新程序集选择注册,然后选择注册新程序集。
  6. 在步骤 1 中选择 (...) 按钮,然后选择前面步骤中构建的 dll。
  7. 选择注册所选插件

注册步骤

  1. 从已注册程序集的列表中选择 CustomValidationPlugin
  2. 选择注册新步骤
  3. 在消息文本字段中输入 msdynmkt_validateformsubmission
  4. 确保将执行模式设置为同步确保将执行模式设置为同步。
  5. 确保执行顺序设置为 10
  6. 确保将执行的事件管道阶段设置为后操作
  7. 选择注册新步骤

结束语

当提交具有 data-validate-submission 属性的窗体时,您的自定义插件将运行并使用 Google 服务验证 reCAPTCHA 响应。 自定义插件在默认的 Microsoft 验证插件之后运行。 如果窗体中没有 Microsoft captcha 字段,Microsoft 插件会设置 IsValid:false,除非您使用 IsValid:true 覆盖它,否则提交将失败。

验证流。