如何在没有页面构建器的情况下在 Kentico 12 中使用 BizForms
How to use BizForms in Kentico 12 without page builder
Kentico 12 仅支持使用开箱即用的 "Form" 页面构建器小部件的表单。
任何人都可以提供示例说明如何在 MVC _Layout.cshtml 或不使用页面构建器的页面中使用 BizForms 吗?
验收标准:
- 必须允许 CMS 用户编辑表单并将更改反映在网站上
- 必须允许开发人员 manipulate/transform 在保存到 Kentico 和发送 notifications/autoresponders
之前提交的数据
- 必须正确呈现表单构建器中使用的自定义 FormSections 和自定义 FormComponents
哈迪斯,
您可以使用 Forms API (https://docs.kentico.com/api12/content-management/form-data) 来 save/access 表单数据并为其实现完全自定义的布局。
希望对您有所帮助!
您可以查看 MVC 项目中的 Kentico.Forms.Web.Mvc.Widgets
命名空间(它应该默认包含)。
其中有一个 KenticoFormWidgetController
控制器 class,它呈现部分表单并接受表单提交。您可以使用该控制器的 Index 路由来呈现您的部分表单,但我不知道该路由的具体外观。
如果您可以访问 Kentico 的源代码,您可以自己检查它的内部结构。
Form 小部件使用以下视图结构和视图模型的组合呈现 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 post编辑了 blog about how to make this work。
该解决方案需要使用 Kentico 的一些内部 API 来使用表单小部件呈现表单生成器并将该代码放入控制器操作中。
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)
};
我采纳了这个想法并写了一篇后续文章 post,Kentico EMS: MVC Widget Experiments Part 3 - Rendering Form Builder Forms Without Widgets,这表明我们还可以使用 Kentico 的预构建表单小部件视图代码来获得预期的呈现和表单提交功能.
<!-- ~/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)
}
Kentico 12 仅支持使用开箱即用的 "Form" 页面构建器小部件的表单。
任何人都可以提供示例说明如何在 MVC _Layout.cshtml 或不使用页面构建器的页面中使用 BizForms 吗?
验收标准:
- 必须允许 CMS 用户编辑表单并将更改反映在网站上
- 必须允许开发人员 manipulate/transform 在保存到 Kentico 和发送 notifications/autoresponders 之前提交的数据
- 必须正确呈现表单构建器中使用的自定义 FormSections 和自定义 FormComponents
哈迪斯, 您可以使用 Forms API (https://docs.kentico.com/api12/content-management/form-data) 来 save/access 表单数据并为其实现完全自定义的布局。 希望对您有所帮助!
您可以查看 MVC 项目中的 Kentico.Forms.Web.Mvc.Widgets
命名空间(它应该默认包含)。
其中有一个 KenticoFormWidgetController
控制器 class,它呈现部分表单并接受表单提交。您可以使用该控制器的 Index 路由来呈现您的部分表单,但我不知道该路由的具体外观。
如果您可以访问 Kentico 的源代码,您可以自己检查它的内部结构。
Form 小部件使用以下视图结构和视图模型的组合呈现 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 post编辑了 blog about how to make this work。
该解决方案需要使用 Kentico 的一些内部 API 来使用表单小部件呈现表单生成器并将该代码放入控制器操作中。
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)
};
我采纳了这个想法并写了一篇后续文章 post,Kentico EMS: MVC Widget Experiments Part 3 - Rendering Form Builder Forms Without Widgets,这表明我们还可以使用 Kentico 的预构建表单小部件视图代码来获得预期的呈现和表单提交功能.
<!-- ~/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)
}