Kentico 12 仅支持使用开箱即用的“表单”页面构建器小部件的表单。
谁能提供如何在 MVC _Layout.cshtml 或不使用页面构建器的页面中使用 BizForms 的示例?
验收标准:
- 必须允许 CMS 用户编辑表单并将更改反映在网站上
- 必须允许开发人员在保存到 Kentico 之前和发送通知/自动回复之前操作/转换提交的数据
- 必须正确呈现表单构建器中使用的自定义 FormSections 和自定义 FormComponents
Kentico 12 仅支持使用开箱即用的“表单”页面构建器小部件的表单。
谁能提供如何在 MVC _Layout.cshtml 或不使用页面构建器的页面中使用 BizForms 的示例?
验收标准:
表单小部件是使用以下视图结构和视图模型的组合呈现的FormWidgetViewModel
:
using (Ajax.Kentico().BeginForm( ... ))
{
@Html.AntiForgeryToken()
@Html.Kentico().FormFields(Model.FormComponents, Model.FormConfiguration, FormFieldRenderingConfiguration.Widget)
// Render Model.SubmitButtonImage using @Html.Kentico().ImageInput( ... )
// Or render a plain <input> using Model.SubmitButtonText
}
如果您有BizFormInfo
表单的对象,则以下属性需要它:
new FormWidgetViewModel
{
FormName = formInfo.FormName,
FormConfiguration = IFormBuilderConfigurationRetriever.Retrieve(formInfo),
FormComponents = IFormProvider.GetFormComponents(formInfo).GetDisplayedComponents( ... ),
FormPrefix = // This may be optional outside of the Page Builder context,
SubmitButtonText = formInfo.FormSubmitButtonText,
SubmitButtonImage = formInfo.FormSubmitButtonImage
}
在里面Ajax.Kentico().BeginForm
你可以传入控制器和处理表单的动作。
使用方法IFormProvider
来更新或添加表单提交并发送电子邮件。
更新(见评论):
IFormBuilderConfigurationRetriever
被标记internal
,所以它不能直接访问。它的实现反过来用于IFormBuilderConfigurationSerializer
反序列化formInfo.FormBuilderLayout
. 那个接口也有标记internal
。此外,该接口的实现使用internal
FormBuilderTypesBinder
.
这意味着没有可用于检索的 API Model.FormConfiguration
。从 Kentico 12.0.16 开始,您需要重新创建内部功能。基本实现是这样的:
JsonConvert.DeserializeObject<FormBuilderConfiguration>(formInfo.FormBuilderLayout, new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
TypeNameHandling = TypeNameHandling.Auto,
SerializationBinder = // Set to the internal FormBuilderTypesBinder, which validates only known form builder types
StringEscapeHandling = StringEscapeHandling.EscapeHtml
});
OP 发布了一篇关于如何完成这项工作的博客。
该解决方案需要使用 Kentico 的一些内部 API 来使用 Form Widgets 渲染 Form Builder,并将该代码放入 Controller 操作中。
var formInfo = BizFormInfoProvider
.GetBizFormInfo(formName, SiteContext.CurrentSiteName);
string className = DataClassInfoProvider
.GetClassName(formInfo.FormClassID);
var existingBizFormItem = className is null
? null
: BizFormItemProvider
.GetItems(className)?.GetExistingItemForContact(
formInfo, contactContext.ContactGuid);
var formComponents = formProvider
.GetFormComponents(formInfo)
.GetDisplayedComponents(
ContactManagementContext.CurrentContact,
formInfo, existingBizFormItem, visibilityEvaluator);
var settings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
TypeNameHandling = TypeNameHandling.Auto,
StringEscapeHandling = StringEscapeHandling.EscapeHtml
};
var formConfiguration = JsonConvert.DeserializeObject<FormBuilderConfiguration>(
formInfo.FormBuilderLayout, settings);
return new FormWidgetViewModel
{
DisplayValidationErrors = true,
FormComponents = formComponents.ToList(),
FormConfiguration = formConfiguration,
FormName = formName,
FormPrefix = Guid.NewGuid().ToString(),
IsFormSubmittable = true,
SiteForms = new List<SelectListItem>(),
SubmitButtonImage = formInfo.FormSubmitButtonImage,
SubmitButtonText = string.IsNullOrEmpty(formInfo.FormSubmitButtonText)
? ResHelper.GetString("general.submit")
: ResHelper.LocalizeString(formInfo.FormSubmitButtonText)
};
我接受了这个想法并写了一篇后续文章,Kentico EMS: MVC Widget Experiments Part 3 - Rendering Form Builder Forms without Widgets,这表明我们还可以使用 Kentico 的预构建 Form Widget 视图代码来获得预期的渲染和表单提交功能。
<!-- ~/Views/Form/Form.cshtml -->
@using Kentico.Forms.Web.Mvc;
@using Kentico.Forms.Web.Mvc.Widgets;
@using Kentico.Forms.Web.Mvc.Widgets.Internal
@model FormWidgetViewModel
@{
var config = FormWidgetRenderingConfiguration.Default;
// @Html.Kentico().FormSubmitButton(Model) requires
// this ViewData value to be populated. Normally it
// executes as part of the Widget rendering, but since
// we aren't rendering a Widget, we have to do it manually
ViewData.AddFormWidgetRenderingConfiguration(config);
}
@using (Html.Kentico().BeginForm(Model))
{
@Html.Kentico().FormFields(Model)
@Html.Kentico().FormSubmitButton(Model)
}
Hades,您可以使用 Forms API ( https://docs.kentico.com/api12/content-management/form-data ) 来保存/访问表单数据并为其实现完全自定义的布局。希望有帮助!
您可以查看Kentico.Forms.Web.Mvc.Widgets
MVC 项目中的命名空间(默认情况下应该包含它)。
其中有一个KenticoFormWidgetController
控制器类,它呈现表单部分并接受表单提交。您可以使用该控制器的 Index 路由来呈现表单的一部分,但是我不知道该路由的外观如何。
如果您可以访问 Kentico 的源代码,您可以自己检查它的内部结构。