在Umbraco中创建支持隐形企业版reCaptcha的自定义字段类型
我发现Umbraco暂无支持隐形企业版reCaptcha的选项,查阅Umbraco官方文档后,尝试通过创建自定义字段类型及自定义验证逻辑来实现该功能。
已完成的开发工作
1. 自定义字段类 ReCaptchaEnterprise.cs
using System; using System.Collections.Generic; using System.Linq; using Microsoft.AspNetCore.Http; using Umbraco.Forms.Core.Enums; using Umbraco.Forms.Core.Models; using Umbraco.Forms.Core.Services; namespace FormsExtensions { public class ReCaptchaEnterprise : Umbraco.Forms.Core.FieldType { public ReCaptchaEnterprise() { Id = new Guid("e3ab6a21-bc99-4cb8-999e-ad01203d61bd"); // Replace this! Name = "ReCaptcha Enterprise"; Description = "Render a custom reCaptcha enterprise field."; Icon = "icon-autofill"; SortOrder = 10; FieldTypeViewName = "FieldType.ReCaptchaEnterprise.cshtml"; } // Custom validation in here which will occur when the form is submitted. // Any strings returned will cause the submission to be considered invalid. // Returning an empty collection of strings will indicate that it's valid to proceed. public override IEnumerable<string> ValidateField(Form form, Field field, IEnumerable<object> postedValues, HttpContext context, IPlaceholderParsingService placeholderParsingService, IFieldTypeStorage fieldTypeStorage) { var returnStrings = new List<string>(); if (!postedValues.Any(value => value.ToString().ToLower().Contains("custom"))) { returnStrings.Add("You need to include 'custom' in the field!"); } var reCaptchaResponse = context.Request.Form["g-recaptcha-response"].ToString(); Console.WriteLine("+++++++++++++++++++++ReCaptcha response+++++++++++++++++++++++++++" + reCaptchaResponse); // Also validate it against the default method (to handle mandatory fields and regular expressions) return base.ValidateField(form, field, postedValues, context, placeholderParsingService, fieldTypeStorage, returnStrings); } } }
2. 前端渲染视图 FieldType.ReCaptchaEnterprise.cshtml
@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage @using Umbraco.Forms.Web @using Microsoft.Extensions.Configuration @model Umbraco.Forms.Web.Models.FieldViewModel @inject IConfiguration Configuration @{ var siteKey = Configuration.GetSection("ReCaptchaEnterprise")["SiteKey"]; if (!string.IsNullOrEmpty(siteKey)) { Html.AddFormThemeScriptFile("https://www.google.com/recaptcha/enterprise.js?render=" + siteKey); <div class="g-recaptcha" data-sitekey="@siteKey" data-callback="onSubmit" data-size="invisible"> </div> <input type="hidden" name="g-recaptcha-response" /> <script type="application/javascript"> function onSubmit(event){ event.preventDefault(); grecaptcha.execute(); } </script> } else { <p class="error">ERROR: reCAPTCHA is missing the Site Key. Please update the configuration to include a value.</p> } }
3. 注册自定义字段到Umbraco容器
using FormsExtensions; using Umbraco.Cms.Core.Composing; using Umbraco.Cms.Core.DependencyInjection; using Umbraco.Forms.Core.Providers; namespace Web { public class ReCaptchaEnterpriseComposer: IComposer { public void Compose(IUmbracoBuilder builder) { builder.WithCollectionBuilder<FieldCollectionBuilder>() .Add<ReCaptchaEnterprise>(); } } }
4. Umbraco后台字段配置视图 App_plugins/UmbracoForms/backoffice/common/fieldtypes/ReCaptchaEnterprise.html
<div class="g-recaptcha" data-sitekey="<site-key>" data-size="invisible"></div>
遇到的问题
我已成功在表单中添加该reCaptcha企业版字段,但在内容模块中通过富文本编辑器>宏添加时,抛出以下异常:
Received an error from the server
An error occurred
Cannot bind source type Umbraco.Forms.Web.Models.FieldViewModel to model type Umbraco.Cms.Core.Models.PublishedContent.IPublishedContent.Exception Details
Umbraco.Cms.Web.Common.ModelBinders.ModelBindingException, Umbraco.Web.Common, Version=12.0.1.0, Culture=neutral, PublicKeyToken=null: Cannot bind source type Umbraco.Forms.Web.Models.FieldViewModel to model type Umbraco.Cms.Core.Models.PublishedContent.IPublishedContent.
已经调试两天仍未找到解决方案,恳请各位提供解决思路,或分享在Umbraco中创建自定义字段的经验,非常感谢!我已参考其他类似实现reCaptcha的包,但并未解决问题。
内容的提问来源于stack exchange,提问作者user23745000

