门户中的多选选项集,或可行的替代方案
Multiselect option set in portal, or viable alternatives
我有一个应用程序实体表单,其中包含 3 个多 select 选项集,这些选项集根据所选的值确定表单的其余部分将出现哪些问题。我需要它出现在我的门户网站上,或者一个可行的替代方案。
multiselect 选项集不会在门户中呈现
Dynamics V9.0 引入了多选选项集,但这种新的字段类型不支持在门户中呈现(..还)。
有一个记录良好的变通方法(不使用 OOB 多选选项集)来创建在门户中呈现为多选选项集的内容:
https://nishantrana.me/2017/03/06/configuring-multiple-choice-field-for-web-form-in-portal-dynamics-365/
TL:DR 是为实体上的每个选项创建一个布尔值(两个选项)字段,并使用表单元数据创建 "Multi Select" 将在门户上呈现的字段。
在您的示例中,您需要创建 3 组字段。
这种方法的一些注意事项是:
- 每个选项集中的选项数
- 期权的波动性(它们多久改变一次)
- 是选项集吗related/filtered
有一些可能的选项需要插件和自定义液体开发,但希望这种方法能满足您的要求。
编辑:我对多选选项集和 Liquid 的经验有限,但我试图创建一个 returns JSON 带有联系人的 Web 模板,其中 cf_interests 字段是多选字段。
以下并非完整答案
{% fetchxml feed %}
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false" count="10" returntotalrecordcount="true" {% if request.params['page'] %} page="{{request.params['page']}}" {% else %} page="1" {% endif %}>
<entity name="contact" >
<attribute name="fullname" />
<attribute name="cf_interests" />
<filter>
<condition attribute="statecode" operator="eq" value="0" />
{% if request.params['id'] %}
<condition attribute="contactid" operator="eq" value="{{ request.params['id' | xml_escape}}" />
{% endif %}
</filter>
</entity>
</fetch>
{% endfetchxml %}{
{% for contact in feed.results.entities %}
{
"fullname": "{{ contact.fullname}}",
"interest": "{{ contact.cf_interests | join: ", " }}"
"interests: "{% for interest in contact.cf_interests%}
{
"interest-{{forloop.index}}": "{{contact.cf_interest[{{forloop.index}}]}}"
}{% unless forloop.last %},{% endunless %}
{% endfor -%}
}{% unless forloop.last %},{% endunless %}
{% endfor -%}
}
理想情况下,这会拉取所有联系人(如果作为参数传递,则通过 ID 进行联系)以及他们的姓名和所有兴趣。此 returns 生成 XRM 工具箱,但门户网站上没有任何内容:
使用的提取:
获取结果:
JSON 网页模板的输出:
无论如何,一旦用户与您要创建的自定义多选控件进行交互,您就需要使用网络 api 来更新多选。我希望使用 JSON 网页模板来驱动该控件。
还有一个新的 class 您可以在插件中或通过网络使用 api 来检索和设置多选选项集
https://docs.microsoft.com/en-us/dynamics365/customer-engagement/developer/multi-select-picklist
我创建了一个在创建和更新联系人时注册的简单示例插件,它将选定的选项集值写入新字符串:
using System;
using System.ServiceModel;
using System.Text;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
namespace PortalMultiSelect
{
public class ContactPostCreateUpdate : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
// Obtain the tracing service
ITracingService tracingService =
(ITracingService)serviceProvider.GetService(typeof(ITracingService));
// Obtain the execution context from the service provider.
IPluginExecutionContext context = (IPluginExecutionContext)
serviceProvider.GetService(typeof(IPluginExecutionContext));
string className = "ContactPostCreateUpdate";
// The InputParameters collection contains all the data passed in the message request.
if (context.InputParameters.Contains("Target") &&
context.InputParameters["Target"] is Entity)
{
// Obtain the target entity from the input parameters.
Entity entity = (Entity)context.InputParameters["Target"];
// Obtain the organization service reference which you will need for
// web service calls.
IOrganizationServiceFactory serviceFactory =
(IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
tracingService.Trace("Message " + context.MessageName);
if (context.MessageName != "Create" && context.MessageName != "Update")
return;
if (context.Depth > 1)
return;
tracingService.Trace(string.Format("Primary EntityNname: {0} and Depth is: {1} ", context.PrimaryEntityName, context.Depth));
if (context.PrimaryEntityName != "contact")
return; //Should only be registerd on Contact Entity
try
{
Guid contactid = context.PrimaryEntityId;
Entity contact = service.Retrieve("contact", contactid, new ColumnSet(true));
tracingService.Trace("{0}: Setting up interest collection", className);
// It will returns the Collection of Values in the OptionSet.
OptionSetValueCollection interests = (OptionSetValueCollection)contact.Attributes["cf_interests"];
string interestValues = string.Empty;
StringBuilder sb = new StringBuilder();
tracingService.Trace("{0}: Joining interest values to string", className);
foreach (OptionSetValue interest in interests)
{
sb.Append(interest.Value).Append(";");
}
interestValues = sb.ToString(0, sb.Length - 1);
contact["cf_intereststring"] = interestValues;
service.Update(contact);
}
catch (FaultException<OrganizationServiceFault> ex)
{
throw new InvalidPluginExecutionException(string.Format("An error occurred in {0}. {1}", className, ex));
}
catch (Exception ex)
{
tracingService.Trace("{0}: {1}",className ,ex.ToString());
throw;
}
}
}
}
}
新 TL:DR 多选选项集是新的并且有很多限制。
我有一个应用程序实体表单,其中包含 3 个多 select 选项集,这些选项集根据所选的值确定表单的其余部分将出现哪些问题。我需要它出现在我的门户网站上,或者一个可行的替代方案。
multiselect 选项集不会在门户中呈现
Dynamics V9.0 引入了多选选项集,但这种新的字段类型不支持在门户中呈现(..还)。
有一个记录良好的变通方法(不使用 OOB 多选选项集)来创建在门户中呈现为多选选项集的内容: https://nishantrana.me/2017/03/06/configuring-multiple-choice-field-for-web-form-in-portal-dynamics-365/
TL:DR 是为实体上的每个选项创建一个布尔值(两个选项)字段,并使用表单元数据创建 "Multi Select" 将在门户上呈现的字段。
在您的示例中,您需要创建 3 组字段。
这种方法的一些注意事项是:
- 每个选项集中的选项数
- 期权的波动性(它们多久改变一次)
- 是选项集吗related/filtered
有一些可能的选项需要插件和自定义液体开发,但希望这种方法能满足您的要求。
编辑:我对多选选项集和 Liquid 的经验有限,但我试图创建一个 returns JSON 带有联系人的 Web 模板,其中 cf_interests 字段是多选字段。
以下并非完整答案
{% fetchxml feed %}
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false" count="10" returntotalrecordcount="true" {% if request.params['page'] %} page="{{request.params['page']}}" {% else %} page="1" {% endif %}>
<entity name="contact" >
<attribute name="fullname" />
<attribute name="cf_interests" />
<filter>
<condition attribute="statecode" operator="eq" value="0" />
{% if request.params['id'] %}
<condition attribute="contactid" operator="eq" value="{{ request.params['id' | xml_escape}}" />
{% endif %}
</filter>
</entity>
</fetch>
{% endfetchxml %}{
{% for contact in feed.results.entities %}
{
"fullname": "{{ contact.fullname}}",
"interest": "{{ contact.cf_interests | join: ", " }}"
"interests: "{% for interest in contact.cf_interests%}
{
"interest-{{forloop.index}}": "{{contact.cf_interest[{{forloop.index}}]}}"
}{% unless forloop.last %},{% endunless %}
{% endfor -%}
}{% unless forloop.last %},{% endunless %}
{% endfor -%}
}
理想情况下,这会拉取所有联系人(如果作为参数传递,则通过 ID 进行联系)以及他们的姓名和所有兴趣。此 returns 生成 XRM 工具箱,但门户网站上没有任何内容:
使用的提取:
获取结果:
JSON 网页模板的输出:
无论如何,一旦用户与您要创建的自定义多选控件进行交互,您就需要使用网络 api 来更新多选。我希望使用 JSON 网页模板来驱动该控件。
还有一个新的 class 您可以在插件中或通过网络使用 api 来检索和设置多选选项集
https://docs.microsoft.com/en-us/dynamics365/customer-engagement/developer/multi-select-picklist
我创建了一个在创建和更新联系人时注册的简单示例插件,它将选定的选项集值写入新字符串:
using System;
using System.ServiceModel;
using System.Text;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
namespace PortalMultiSelect
{
public class ContactPostCreateUpdate : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
// Obtain the tracing service
ITracingService tracingService =
(ITracingService)serviceProvider.GetService(typeof(ITracingService));
// Obtain the execution context from the service provider.
IPluginExecutionContext context = (IPluginExecutionContext)
serviceProvider.GetService(typeof(IPluginExecutionContext));
string className = "ContactPostCreateUpdate";
// The InputParameters collection contains all the data passed in the message request.
if (context.InputParameters.Contains("Target") &&
context.InputParameters["Target"] is Entity)
{
// Obtain the target entity from the input parameters.
Entity entity = (Entity)context.InputParameters["Target"];
// Obtain the organization service reference which you will need for
// web service calls.
IOrganizationServiceFactory serviceFactory =
(IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
tracingService.Trace("Message " + context.MessageName);
if (context.MessageName != "Create" && context.MessageName != "Update")
return;
if (context.Depth > 1)
return;
tracingService.Trace(string.Format("Primary EntityNname: {0} and Depth is: {1} ", context.PrimaryEntityName, context.Depth));
if (context.PrimaryEntityName != "contact")
return; //Should only be registerd on Contact Entity
try
{
Guid contactid = context.PrimaryEntityId;
Entity contact = service.Retrieve("contact", contactid, new ColumnSet(true));
tracingService.Trace("{0}: Setting up interest collection", className);
// It will returns the Collection of Values in the OptionSet.
OptionSetValueCollection interests = (OptionSetValueCollection)contact.Attributes["cf_interests"];
string interestValues = string.Empty;
StringBuilder sb = new StringBuilder();
tracingService.Trace("{0}: Joining interest values to string", className);
foreach (OptionSetValue interest in interests)
{
sb.Append(interest.Value).Append(";");
}
interestValues = sb.ToString(0, sb.Length - 1);
contact["cf_intereststring"] = interestValues;
service.Update(contact);
}
catch (FaultException<OrganizationServiceFault> ex)
{
throw new InvalidPluginExecutionException(string.Format("An error occurred in {0}. {1}", className, ex));
}
catch (Exception ex)
{
tracingService.Trace("{0}: {1}",className ,ex.ToString());
throw;
}
}
}
}
}
新 TL:DR 多选选项集是新的并且有很多限制。