適用於:僅限 Dynamics 365 Contact Center — 獨立和 Dynamics 365 Customer Service
本文介紹將資訊從外部數據提供程式映射到知識文章實體所需的架構詳細資訊,以及如何使用各種欄位和屬性準備自己的架構映射 JSON 檔。
欄位
下表列出了您必須在 JSON 架構中使用的欄位和欄位詳細資訊。
| 欄位名稱 | 定義 | 為必填項目 | 價值觀 |
|---|---|---|---|
| 名稱 | 欄位定義的名稱 | 否 | 指示欄位名稱的字串。 |
| UniqueTargetFieldName | 知識文章實體的唯一標識碼或備用鍵。 通常,此欄位是內容供應商端的 ID。 | 是的 | 指示欄位名稱的字串。 您可以將該值設置為 “msydn_externalreferenceid” |
| ContentTargetFieldName | 欄位值不應更改。 | 是的 | 將值設置為 「content」。。 |
| ApiPathLeafName | 欄位值不應更改。 | 是的 | 將值設置為 「knowledgearticles」。 |
| 列出<欄位定義> | 是欄位定義的清單。 | 是的 | 欄位的一組定義。 有關設置欄位定義的支援欄位清單,請參閱下表。 |
欄位定義
下表列出了您可以在元數據映射架構中使用的必需和可選屬性。
| 欄位名稱 | 定義 | 為必填項目 | 價值觀 |
|---|---|---|---|
| TargetFieldName | 是知識文章實體中目標屬性的邏輯欄位名稱。 | 是的 | 指示目標欄位名稱的任何字串 |
| TargetFieldType | 指示目標欄位的類型。 | 是的 | 一個字串,指示欄位的類型。 |
| DocFieldSource | 指示在運行時如何識別和解析源欄位值 | 是的 | 將值設定為以下來源類型之一:
|
| DocFieldPattern | 指示要獲取的目標欄位的性質。 | 否 | 根據 DocFieldSource 值設置此值。 請參閱下面的示例,瞭解如何設置 DocFieldPatterns。 |
| MaxLength | 是可以存儲在目標欄位中的字符串的最大長度。 | 否。 當 TargetFieldType 屬性的類型為 String 時,可以使用該屬性 | 整數 |
| UseRegexCapture | 儲存可應用於 URL 的正則表達式。 | 否。 當 TargetFieldType 屬性的類型為 String 且 DocFieldSource 屬性的類型為 Url 時,可以使用。 | URL 或字串。 |
欄位來源類型
外部搜尋提供程式中的數據可以設定為以下任何欄位源型態:
- Regex:用於指示數據的正規表示式類型。
- Meta:用於指示目標欄位值是從源文章中的 <meta> 標籤獲取的
- 常量:用於設置目標欄位的靜態值。
- URL:用於指示外部源文檔的 URL。
- 文檔:用於指示文章的 HTML 內容。
構建自己的元數據映射範本的注意事項
在開發自己的映射架構時,必須確保配置一些必填欄位併為某些欄位定義設置預設值。
您的映射樣本必須包括:
UniqueTargetFieldName、ContentTargetFieldName 和 ApiPathLeafName 字段。 這些欄位必須設置為其必需值,如下所示:
- 將 UniqueTargetFieldName 設定為現成的 msdyn_externalreferenceid 欄位或自訂欄位。 如果您使用的是自定義欄位,請確保將該欄位添加為備用鍵。 詳細資訊: 定義引用 Dynamics 365 記錄的備用鍵。
- 包括 ContentTargetFieldName 欄位並將其值設置為「content」。
- 包括 ApiPathLeafName 字段並將其值設置為“knowledgearticles”。
- 確保在 FieldDefinitions 清單中為 UniqueTargetField 和 ContentTargetField 字段提供映射。
您的映射架構將如下所示:
{ "Name": "{To be filled by you}", "UniqueTargetFieldName": "msdyn_externalreferenceid", "ContentTargetFieldName": "content", "ApiPathLeafName": "knowledgearticles" "FieldDefinitions": [] }您必須包含以下 FieldDefinitions 清單,並使用預設值填充其屬性,例如 FieldUse、 DocFieldSource、 TargetFieldName 和 TargetFieldType 。 請務必在範本中包含以下字段和屬性及其值「as-is」。 但是,您可以將標題和內容值字段的 Docfieldsource 和 Docfieldpattern 設置為 Regex、 Meta、 Document、 Constant 或 Url。
{ "FieldUse": "Create", "DocFieldSource": "ArticlePublicNumber", "TargetFieldName": "articlepublicnumber", "TargetFieldType": "String" }, { "DocFieldSource": "Constant", "DocFieldPattern": "true", "TargetFieldName": "msdyn_isingestedarticle", "TargetFieldType": "Boolean" }, { "DocFieldSource": "Url", "TargetFieldName": "msdyn_ingestedarticleurl", "TargetFieldType": "String" }, { "DocFieldSource": "DataProvider", "TargetFieldName": "msdyn_integratedsearchproviderid@odata.bind", "TargetFieldType": "String" }, { "DocFieldSource": "Regex", "DocFieldPattern": "<title>(.*?)</title>", "TargetFieldName": "title", "TargetFieldType": "String" }, { "DocFieldSource": "Url", "TargetFieldName": "msdyn_externalreferenceid", "TargetFieldType": "String", "UseRegexCapture": "^https://.*?/(.*?)/.*/.*?([0-9A-F]{8}[-](?:[0-9A-F]{4}[-]){3}[0-9A-F]{12})$" }, { "DocFieldSource": "Document", "TargetFieldName": "content", "TargetFieldType": "String" }列出必填欄位和屬性資訊後,您可以包含任何其他元數據映射併為其設置自己的自定義值。 例如,您可以包括 DocFieldSource 的 Meta 類型,併為該屬性設置任何自定義值,如下所示。
{ "DocFieldSource": "Meta", "DocFieldPattern": "description", "TargetFieldName": "description", "TargetFieldType": "String", "MaxLength": 155 }
範例元數據映射範本
您可以使用以下元數據映射 JSON 範例作為範本來建構您自己的自訂映射範本。
{
"Name": "Integrated Search Data Provider Name",
"UniqueTargetFieldName": "msdyn_externalreferenceid",
"ContentTargetFieldName": "content",
"ApiPathLeafName": "knowledgearticles",
"FieldDefinitions": [
{
"FieldUse": "Create",
"DocFieldSource": "ArticlePublicNumber",
"TargetFieldName": "articlepublicnumber",
"TargetFieldType": "String"
},
{
"DocFieldSource": "Constant",
"DocFieldPattern": "true",
"TargetFieldName": "msdyn_isingestedarticle",
"TargetFieldType": "Boolean"
},
{
"DocFieldSource": "Url",
"TargetFieldName": "msdyn_ingestedarticleurl",
"TargetFieldType": "String"
},
{
"DocFieldSource": "DataProvider",
"TargetFieldName": "msdyn_integratedsearchproviderid@odata.bind",
"TargetFieldType": "String"
},
{
"DocFieldSource": "Regex",
"DocFieldPattern": "<title>(.*?)</title>",
"TargetFieldName": "title",
"TargetFieldType": "String"
},
{
"DocFieldSource": "Meta",
"DocFieldPattern": "description",
"TargetFieldName": "description",
"TargetFieldType": "String",
"MaxLength": 155
},
{
"DocFieldSource": "Document",
"TargetFieldName": "content",
"TargetFieldType": "String"
},
{
"DocFieldSource": "Url",
"TargetFieldName": "msdyn_externalreferenceid",
"TargetFieldType": "String",
"UseRegexCapture": "^https://.*?/(.*?)/.*/.*?([0-9A-F]{8}[-](?:[0-9A-F]{4}[-]){3}[0-9A-F]{12})$"
}
]
}
轉換外部源數據並將其映射到知識欄位
當您將資訊從外部資料提供者對應至知識文章實體時,如果來源值屬於不同的資料類型,則必須先轉換值,才能將其對應至目標知識屬性。 您可以建立一個插件,並將其註冊到 Create 和 Update 訊息,以便目標知識文章的屬性具有與外部提供者的文章相符的值。
若要轉換和對應來源值,請執行下列步驟:
- 在實體中
KnowledgeArticle建立自訂欄位。 如需詳細資訊,請參閱 如何建立和編輯欄。 - 將所需的外部來源值對應至新建立的自訂欄位。 如需詳細資訊,請參閱設定知識文章架構對應 (預覽版)。 這是外掛程式從中挑選來源值的暫時對應。
- 建立外掛程式。 如需詳細資訊,請參閱建立外掛程式專案。
- 您可以撰寫自己的程式碼來轉換外部來源值,並將其對應至所需的目標知識文章屬性。
在此範例中,我們示範如何將 String 類型的來源值對應至 OptionSet 類型的文章欄位屬性。 在您建立的外掛程式中,將整個類別取代為下列範例程式碼。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting.Contexts;
using System.Runtime.Remoting.Services;
using System.ServiceModel;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Metadata;
namespace PowerApps.Samples
{
/// <summary>
/// The plug-in shows the sample code to map the external source value to the target attribute, when they're of different types
/// </summary>
/// <remarks>
/// To showcase the capabilities of the plugin, we have added 2 new attributes to the KnowledgeArticle entity.
/// The first attribute new_documentationcentersourcevalue is a String attribute that is mapped to the external source value. This is a temporary mapping that stores the source value.
/// The plugin picks up the source value from new_documentationcentersourcevalue. The source value can take the following values: Develop, Content, and Test.
///The second attribute, new_documentationcenter, is the target attribute of type OptionSet to which the source value must actually be mapped to.
/// Develop with value 100000000, Content with value 100000001, and Test with value 100000002
/// The goal of this plugin to read the value from the new_documentationcentersourcevalue, retrieve the option set metadata of the target attribute new_documentationcenter, and map it to the value in new_documentationcentersourcevalue.
/// </remarks>
public sealed class KnowledgePlugin : IPlugin
{
/// <summary>
/// Execute method that is required by the IPlugin interface.
/// </summary>
/// <param name="serviceProvider">The service provider from which you can obtain the
/// tracing service, plug-in execution context, organization service, and more.</param>
public void Execute(IServiceProvider serviceProvider)
{
//Extract the tracing service for use in debugging sandboxed plug-ins.
ITracingService tracingService =
(ITracingService)serviceProvider.GetService(typeof(ITracingService));
// Obtain the execution context from the service provider.
IPluginExecutionContext context = (IPluginExecutionContext)
serviceProvider.GetService(typeof(IPluginExecutionContext));
// 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"];
// Verify that the target entity represents knowledgearticle.
if (entity.LogicalName != "knowledgearticle")
{
tracingService.Trace("KnowledgePlugin: Plugin is incorrectly called for the entity: " + entity.LogicalName);
return;
}
//Skip the plugin for RootArticles
const string isRootArticleAttributeName = "isrootarticle";
bool isRootArticle = entity.GetAttributeValue<bool>(isRootArticleAttributeName);
if (isRootArticle)
{
tracingService.Trace("KnowledgePlugin: Returning for Root Article");
return;
}
try
{
const string sourceValueAttributeName = "new_documentationcentersourcevalue";
const string targetValueAttributeName = "new_documentationcenter";
//Get the source value
string sourceValue = entity.GetAttributeValue<string>(sourceValueAttributeName);
if (string.IsNullOrEmpty(sourceValue))
{
tracingService.Trace("KnowledgePlugin: " + sourceValueAttributeName + " is not set");
return;
}
// Obtain the organization service reference.
IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
// Retrieve the option set metadata of the target field.
OptionSetMetadata retrievedOptionSetMetadata = RetrieveOptionSet(service, entity, targetValueAttributeName, tracingService);
// Check if the source data value is present in the retrieved target option set metadata.
OptionMetadata matchedOptionMetadata = retrievedOptionSetMetadata?.Options?.First(optionMetadata => optionMetadata.Label.UserLocalizedLabel.Label == sourceValue);
if (matchedOptionMetadata == null || matchedOptionMetadata.Value == null)
{
tracingService.Trace("KnowledgePlugin: Matching OptionMetadata is not found");
return;
}
// Map the option set value of the string new_documentationcentersourcevalue to the target option set new_documentationcenter.
int optionSetValue = (int)matchedOptionMetadata.Value;
entity[targetValueAttributeName] = new OptionSetValue(optionSetValue);
tracingService.Trace("KnowledgePlugin: Successfully set the value.");
}
catch (FaultException<OrganizationServiceFault> ex)
{
throw new InvalidPluginExecutionException("An error occurred in the KnowledgePlugin plug-in." + ex + "\n InnerException: " + ex.InnerException);
}
catch (Exception ex)
{
tracingService.Trace("Exception in KnowledgePlugin: {0}", ex);
throw ex;
}
}
}
/// <summary>
/// Fetch the optionset metadata from the entity metadata
/// </summary>
/// <param name="service">Organization Details</param>
/// <param name="entity">Entity record</param>
/// <param name="targetValueAttributeName">Optionset Attribute Name</param>
/// <param name="tracingService">Tracing Service</param>
private OptionSetMetadata RetrieveOptionSet(IOrganizationService service, Entity entity, string targetValueAttributeName, ITracingService tracingService)
{
RetrieveEntityRequest retrieveEntityRequest = new RetrieveEntityRequest
{
LogicalName = entity.LogicalName,
EntityFilters = EntityFilters.Attributes,
RetrieveAsIfPublished = true
};
RetrieveEntityResponse retrieveEntityResponse = (RetrieveEntityResponse)service.Execute(retrieveEntityRequest);
EntityMetadata metadata = retrieveEntityResponse.EntityMetadata;
PicklistAttributeMetadata picklistMetadata = metadata.Attributes.FirstOrDefault(attribute => string.Equals(attribute.LogicalName, targetValueAttributeName, StringComparison.OrdinalIgnoreCase)) as PicklistAttributeMetadata;
return picklistMetadata.OptionSet;
}
}
}
- 在 PreOperation 階段中 KnowledgeArticle 實體的
Create和UpdateSDK 訊息上註冊外掛程式。 其他資訊: 註冊外掛程式