创建和使用自定义 API

使用自定义 API 在 Dataverse 中创建自己的 API。 可以将一个或多个操作合并到自定义 API 中,您和其他开发人员可以在其代码或 Power Automate 中调用这些操作。 Microsoft Dataverse 连接器可在 Power Automate 中启用调用操作。

可以使用自定义 API 作为业务事件来创建新的集成功能,例如在 Microsoft Dataverse 连接器中公开新类型的触发器事件。 详细了解 Microsoft Dataverse 业务事件

自定义 API 是自定义流程操作的替代方法。 自定义流程操作提供了一种零代码实现方法来包含自定义消息,但对开发人员来说存在一些限制。 自定义 API 提供专门为开发人员提供的功能,以使用更多选项在代码中定义其逻辑。 有关自定义进程作和自定义 API 的完整比较,请参阅 “比较自定义进程作”和“自定义 API”。

创建自定义 API

自定义 API 通常包括使用插件实现的逻辑,但不是必需的。 通过使用 Microsoft Dataverse 业务事件,可以创建自定义 API,而无需插件来传递有关其他订阅者响应的事件的数据。

在大多数情况下,将自定义 API 与插件相结合,以定义将某些操作委托给 Dataverse 来计算和返回结果。

可以通过多种不同的方式创建自定义 API:

方法链接 益处
插件注册工具 与用于开发插件的工具集成的易于使用的 GUI 工具。
Power Apps 使用表单输入数据。 无需安装单独的工具,必须为自定义 API 的每个部分创建单独的记录。
带有代码 了解数据模型后,可以使用 Postman 或 Insomnia 等 API 客户端快速创建自定义 API。 或者,你可以构建自己的体验来创建自定义 API。
使用解决方案文件 使用应用程序生命周期管理(ALM)工具时,可以使用源代码存储库中包含的解决方案中的 XML 文件创建或修改自定义 API 定义。 导入从源代码生成的解决方案时,会创建自定义 API。

注释

尽管自定义 API 数据存储在表中,但不支持为这些表创建模型驱动应用。

社区创建和支持这些工具以使用自定义 API:

Microsoft不支持社区创建的工具。 如果您对社区工具有任何疑问或问题,请与该工具的发布者联系。

定制化 API 自定义设置

创建自定义 API 和相关请求参数和响应属性时,请了解这些 API 定义默认可自定义。 如果这些项是可自定义的,则可以在非托管解决方案中迭代并更改这些项。

重要

交付或部署您的解决方案时,请使用托管解决方案,并始终将这些组件的Is Customizable托管属性设置为false。 此设置可防止使用托管解决方案的人员修改或删除这些组件。 此类更改可能会中断为自定义 API 的原始定义编写的代码。

设置“Is Customizable”为 false

在 Power Apps 中,从解决方案中设置可自定义托管属性。

设置“可自定义”托管属性

为每个自定义 API、请求参数和响应属性单独设置此属性。

详细了解托管属性

添加更多请求参数和响应属性

即使将 Is Customable 托管属性 false设置为 ,也可以向自定义 API 添加新的请求参数和响应属性。 但是,添加这些请求参数的人员不能要求这些参数。 如果选择 允许自定义 API 上的自定义处理步骤,则为自定义 API 创建的消息注册的其他插件可以使用它们。 由于自定义请求参数只是可选的,因此你为自定义 API 的主要作提供的插件可以忽略它们,并且不负责使用任何自定义请求参数或设置添加到指定的自定义 API 的任何自定义响应属性。

自定义 API 表和实体

有关创建自定义 API 时要使用的表和列值的信息,请参阅 CustomAPI 表

选择自定义处理步骤类型

下表描述了要使用的自定义 API 自定义处理步骤类型AllowedCustomProcessingStepType)。

选项 何时使用
没有 当使用 CustomAPI.PluginTypeId 为此自定义 API 设置的插件是执行此作时发生的唯一逻辑时使用。
您不允许其他开发人员注册任何能够触发其他逻辑、修改此操作行为或取消该操作的步骤。
当自定义 API 提供一些不应自定义的功能时,请使用此选项。
仅异步 当您希望允许其他开发人员检测到此操作何时发生,但不希望他们能够取消该操作或自定义操作行为时使用。
其他开发人员可以注册异步步骤以检测此操作是否发生,并在操作完成后作出响应。
如果使用业务事件模式,则建议使用此选项。 业务事件在 Power Automate 中创建一个触发器,可在发生此事件时使用该触发器。 了解 Microsoft Dataverse 商业事件
同步和异步 当您希望允许其他开发人员更改操作的行为时使用,并且如果他们的业务逻辑要求,甚至可以取消该操作。
如果作成功,其他开发人员还可以检测此事件并添加逻辑以异步运行。
大多数 Dataverse 消息以这种方式启用扩展。 当消息表示应自定义的业务流程时,请使用此选项。

选择绑定类型

绑定是一个 OData 概念,它将操作与特定表相关联。 下表描述了应使用的自定义 API 绑定类型BindingType)。

选项 何时使用
全球 当操作不适用于特定表时。
实体 当操作接受特定表的单个记录作为参数时。
EntityCollection 当操作将更改应用于特定的数据表或返回其集合时。

选择 EntityEntityCollection 时,需要在使用 Web API 时使用函数或操作的完全限定名称。 完全限定的名称为 Microsoft.Dynamics.CRM.<UniqueName of the custom API>

选择“实体”时,将自动创建一个名为类型Target的请求参数EntityReference。 无需创建它。 此值将传递给为此消息注册的任何插件。

选择 EntityCollection 时,不包含任何表示实体集合的参数或响应属性。 设置此绑定只是增加了一个要求,即在使用 Web API 时,调用的操作追加到实体集。

注释

这些绑定类型可用于撰写自定义 API 时使用,但不需要绑定到实体或实体集合。 可以将所有自定义 API 撰写为 全局 API,并添加需要实现与绑定函数或作相同的功能所需的请求参数或响应属性。

详细信息:

何时创建函数

自定义 API Is Function 属性控制该自定义 API 是 函数 还是 操作。 在 OData 中,函数是使用 HTTP GET 请求调用的作。 它不进行任何更改即可返回数据。 通过使用 GET 请求,在调用函数时传递 URL 中的所有参数。

可以更轻松地单独使用浏览器测试 GET 请求,但可以发送的 URL 长度限制为 32 KB(32,768 个字符)。 如果自定义 API 具有许多复杂的请求参数,可能导致 URL 的长度过长,则可以创建一个执行相同操作的 Action,并使用 POST 请求将所有参数数据传递到正文中。

注释

  • 函数必须返回一些数据。 必须至少包含一个响应属性才能使自定义 API 有效。
    • 不包含响应属性的函数不会显示在 Web API $metadata 服务文档中。
    • 如果尝试使用无效函数,则会收到 404 Not found 类似于下面的错误:
      {"error":{"code":"0x8006088a","message":"Resource not found for the segment 'your_function_name'."}}
  • 选择 “为工作流启用” 选项时,无法使用函数。 请参阅 在工作流中使用自定义 API
  • 目前,Microsoft Dataverse 连接器 仅支持执行操作。 如果需要通过 Power Automate 执行操作,您应该创建自定义 API 作为一个操作。

了解如何使用 Web API 函数

何时将自定义 API 设为专用

默认情况下,其他开发人员可以发现和使用你创建的任何自定义 API。 作为自定义 API 发布者,你负责维护你创建的公共 API。 请勿删除 API 或实施破坏其他使用者的更改。

如果你不愿意使用自定义 API 支持其他开发人员,请在寄送包含自定义 API 的托管解决方案之前将自定义 API Is PrivateIsPrivate) 属性设置为 true。

Is Private 属性阻止自定义 API 出现在$metadata服务文档中,并阻止 Dataverse 代码生成工具创建类以将消息用于自定义 API。

设置此属性并不意味着如果其他开发人员知道它,他们就不能使用您的消息;他们了解消息后,也能够撰写请求来使用它。 设置 Is Private 属性表示你不支持使用你的消息的其他开发人员。

在确保不必删除或引入破坏性更改之前,您可能希望将自定义 API 保持为私有。

“专用” 设置为 false,以便在开发环境中查看$metadata服务文档中的输出或生成类供自己使用。 但是,在托管解决方案中传送自定义 API 之前,请将 “专用” 设置为 true。

详细信息:

通过要求特权来保护自定义 API

将自定义 API 执行特权名称ExecutePrivilegeName) 属性设置为需要该权限的名称。 目前,Microsoft之外的开发人员不支持创建新权限,但可以使用现有权限。 有关详细信息,请参阅 问:是否可以为自定义 API 创建新特权?

使用插件在自定义 API 中包含逻辑

如果未将自定义 API 插件类型PluginTypeId) 设置为指定主作逻辑,用户仍可以调用自定义 API。

可以选择在插件中不包含任何逻辑,因为使用自定义 API 作为业务事件。 了解 Microsoft Dataverse 业务事件

你可能不想将插件添加为测试步骤。 如果没有插件,任何输出参数值都返回类型的默认值,因为没有设置它们的代码。 否则,请参阅 为自定义 API 编写插件

注释

无法将配置数据传递到指定用于主要操作逻辑的插件。 有一种解决方法

在工作流中使用自定义 API

需要启用作为工作流操作调用自定义 API 时,将自定义 API 为工作流启用 (WorkflowSdkStepEnabled) 设置为 true。 但是,此选项添加了以下限制,以便可以在工作流设计器中调用自定义 API:

  • 自定义 API 不能是函数。 Is Function 必须是 false。

  • 自定义 API 只能具有工作流支持的请求参数或响应属性类型:

    • 布尔
    • 日期时间
    • Decimal
    • EntityReference
      • 仅当自定义 API 绑定到实体时,才能使用 EntityReference。
    • 漂浮
    • 整数
    • 金钱
    • 选择列表
    • String
    • Guid

    无法使用以下请求参数或响应属性类型:

    • 实体
    • EntityCollection
    • StringArray

调用自定义 API

自定义 API 将创建一条新消息,用户可以像执行任何其他操作一样通过 Web API 或 Dataverse SDK for .NET 调用。

从 Web API 调用自定义 API

测试时,可以使用 API 客户端,如 Postman 或 Insomnia,来调用 API。 若要设置一个能生成访问令牌的 Insomnia 环境,请参阅 将 Insomnia 与 Dataverse Web API 配合使用。 如果您的 API 是一个操作,请按照 使用 Web API 操作中的步骤进行操作。 如果您的 API 是一个函数,请按照 使用 Web API 函数中的步骤进行操作。

请参阅以下示例:

未绑定操作

此操作被命名为 myapi_CustomUnboundAPI。 它有一个名为InputParameter的单字符串请求参数。

POST [Organization URI]/api/data/v9.1/myapi_CustomUnboundAPI
OData-MaxVersion: 4.0
OData-Version: 4.0
Content-Type: application/json; charset=utf-8

{
  "InputParameter": "Value"
}

绑定到表的函数

名为 myapi_CustomBoundAPI 的函数绑定到帐户表:

GET [Organization URI]/api/v9.1/accounts(ed5d4e42-850c-45b7-8b38-2677545107cc)/Microsoft.Dynamics.CRM.myapi_CustomBoundAPI()
OData-MaxVersion: 4.0
OData-Version: 4.0
Content-Type: application/json; charset=utf-8

绑定到表集合的函数

此名为myapi_CustomEntityCollectionBoundAPI的函数绑定至帐户表集合:

GET [Organization URI]/api/v9.1/accounts/Microsoft.Dynamics.CRM.myapi_CustomEntityCollectionBoundAPI()
OData-MaxVersion: 4.0
OData-Version: 4.0
Content-Type: application/json; charset=utf-8

详细信息:

从用于 .NET 的 SDK 调用自定义 API

若要调用自定义 API,请使用早期绑定或后期绑定代码。 使用 pac modelbuilder 生成 工具生成帮助程序请求和响应类,这些类公开自定义 API 的请求参数和响应属性。 详细了解如何为适用于 .NET 的 SDK 生成早期绑定类

对于后期绑定代码或标记为专用的自定义 API,使用自定义 API 的唯一名称来创建 OrganizationRequest。 添加与请求属性的唯一名称匹配的参数。

实体绑定的自定义 API 具有一个名为 Target 的隐式请求属性。 将此属性设置为 EntityReference 记录项,以调用 API。

可以从返回的响应的参数访问响应属性。

在此示例中,一个名为 myapi_EscalateCase 的自定义 API 绑定到项目表,以接受记录作为 Target 参数,同时还有一个名为 Priority 的选项集值请求参数。 EntityReference它具有一个名为AssignedTo的响应属性。

var req = new OrganizationRequest("myapi_EscalateCase")
{
  ["Target"] = new EntityReference("incident", guid),
  ["Priority"] = new OptionSetValue(1)
};

var resp = svc.Execute(req);

var newOwner = (EntityReference) resp["AssignedTo"];

了解如何将消息与 SDK for .NET 配合使用

将自定义 API 作为后台调用

必须将通过后台操作执行的逻辑定义为自定义 API。了解如何使用后台操作(预览版)

为自定义 API 编写插件

编写一个插件来实现您自定义 API 的主要操作并不与编写其他插件不同。 但是,请勿使用插件注册工具设置特定步骤,并且 无法指定要传递给插件的配置数据

需要了解以下信息:

  • 消息的名称。
  • 请求参数和响应属性的名称和类型。

Request Parameter 值包含在 InputParameters 中

设置 OutputParameters 中响应属性的值。

以下代码是一个简单的插件,用于反转字符 StringParameter ,并返回结果作为 StringProperty

using System;
using System.Linq;
using System.ServiceModel;
using Microsoft.Xrm.Sdk;

namespace CustomAPIExamples
{
    public class Sample_CustomAPIExample : 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));

            if (context.MessageName.Equals("sample_CustomAPIExample") && context.Stage.Equals(30)) {

                try
                {
                    string input = (string)context.InputParameters["StringParameter"];
                    
                    if (!string.IsNullOrEmpty(input)) {
                        //Simply reversing the characters of the string
                        context.OutputParameters["StringProperty"] = new string(input.Reverse().ToArray());
                    }
                }
                catch (Exception ex)
                {
                    tracingService.Trace("Sample_CustomAPIExample: {0}", ex.ToString());
                    throw new InvalidPluginExecutionException("An error occurred in Sample_CustomAPIExample.", ex);
                }
            }
            else
            {
                tracingService.Trace("Sample_CustomAPIExample plug-in is not associated with the expected message or is not registered for the main operation.");
            }
        }
    }
}

有关编写插件的详细信息,请参阅 教程:编写和注册插件。 您需要注册程序集,但不需要注册步骤。 了解如何使用插件在自定义 API 中包含逻辑

请参阅示例 示例:IsSystemAdmin 自定义 API

注册程序集后,请确保将程序集和任何类型添加到解决方案。

本地化的标签值

自定义 API 具有可本地化的标签。 可以使用在模型驱动应用的可本地化文本翻译翻译标签及显示字符串中记录的步骤来本地化标签值。

此过程涉及导出包含基础语言值的文件,并为每个启用的语言提供一列。 然后,可以在 Excel 中编辑值。 完成导入翻译的过程后,标签将包含在解决方案中。

下面的示例演示如何编辑 Excel 工作表以添加英语值的日语翻译。

演示如何本地化标签。

小窍门

如果要编辑解决方案文件以创建自定义 API,可以直接提供本地化标签。 了解如何为本地化标签提供解决方案

设置本地化值

如果想要在代码中设置本地化标签,而不是使用前面所述的手动流程,通过 Web API SetLocLabels 操作或适用于 .NET SetLocLabelsRequest 的 SDK 使用 SetLocLabels 消息。

以下示例演示如何使用 Web API 为 displayname 自定义 API 的属性设置本地化标签。

请求:

POST [Organization URI]/api/data/v9.1/SetLocLabels HTTP/1.1
Accept: application/json
OData-MaxVersion: 4.0
OData-Version: 4.0
Content-Type: application/json

{
    "EntityMoniker": {
        "@odata.type": "Microsoft.Dynamics.CRM.customapi",
        "customapiid": "86bcd12e-2f30-eb11-a813-000d3a122b89"
    },
    "AttributeName": "displayname",
    "Labels": [
        {
            "Label": "例え",
            "LanguageCode": 1041
        },
        {
            "Label": "Beispiel",
            "LanguageCode": 1031
        },
        {
            "Label": "ejemplo",
            "LanguageCode": 1034
        }
    ]
}

响应:

HTTP/1.1 204 No Content

检索本地化值

若要检索本地化标签,请使用 Web API RetrieveLocLabels或用于 .NET RetrieveLocLabelsRequest 类的 SDK 来使用该消息。

以下示例演示如何使用 RetrieveLocLabels 函数来检索 88602189-183d-4584-ba4b-8b60f0f5b89fcustomapiid 的自定义 API 的 displayname 属性的标签。

请求:

GET [Organization URI]/api/data/v9.1/RetrieveLocLabels(EntityMoniker=@p1,AttributeName=@p2,IncludeUnpublished=@p3)?
@p1={'@odata.id':'customapis(88602189-183d-4584-ba4b-8b60f0f5b89f)'}&
@p2='displayname'&
@p3=false HTTP/1.1

响应:

HTTP/1.1 200 OK
OData-Version: 4.0

{
    "@odata.context": "[Organization URI]/api/data/v9.1/$metadata#Microsoft.Dynamics.CRM.RetrieveLocLabelsResponse",
    "Label": {
        "LocalizedLabels": [
            {
                "Label": "Custom API Example",
                "LanguageCode": 1033,
                "IsManaged": null,
                "MetadataId": null,
                "HasChanged": null
            },
            {
                "Label": "カスタムAPIの例",
                "LanguageCode": 1041,
                "IsManaged": null,
                "MetadataId": null,
                "HasChanged": null
            }
        ],
        "UserLocalizedLabel": {
            "Label": "Custom API Example",
            "LanguageCode": 1033,
            "IsManaged": null,
            "MetadataId": null,
            "HasChanged": null
        }
    }
}

常见问题解答 (FAQ)

以下问题和答案可以帮助你:

问:是否可以为自定义 API 创建新特权?

答:虽然自定义 API 具有 “执行权限名称 ”(ExecutePrivilegeName)属性,但目前不支持仅为此 API 创建新特权。 此功能计划在将来的版本中使用。 在此期间,使用以下选项之一:

  • 使用现有 Privilege.Name 值。
  • 创建自定义实体并使用为该实体创建的权限之一。 例如,创建一个名为 new_myaction 的实体,并为为其生成的 CRUD 操作创建权限。 例如: prvCreatenew_myaction。 将此自定义实体包含在包含自定义 API 的解决方案中。

问:是否可以激活或停用自定义 API 记录?

答:你不能。 虽然这些记录在大多数 Microsoft Dataverse 表中都包含常见的 状态状态原因 列,但设置这些列的值不会对自定义 API、请求参数或响应属性的可用性产生影响。

问:如果 Web API $metadata 服务文档中未包含私人消息,应该如何使用这些消息?

答:您的专用消息会正常工作,无论这些消息是否在 Web API CSDL $metadata 文档中播发。 开发解决方案时,请将 IsPrivate 值设置为 false。 可以参考列表 $metadata 并使用依赖于此数据的代码生成工具。 但是,在交付您的解决方案供其他人使用之前,将 CustomAPI.IsPrivate 值设置为 true。 如果以后决定希望支持其他应用程序使用该消息,则可以将 CustomAPI.IsPrivate 值更改为 false

详细信息:

自定义 API 的已知问题

自定义 API 现已正式发布,但某些相关功能可能会更改。

无法使用探查器进行调试

若要使用插件注册工具和插件探查器解决方案进行调试,需要选择特定的插件步骤。 插件的主要阶段实现目前在插件注册工具中不可用。

解决方法:在为自定义 API 创建的消息的阶段注册插件类型 PostOperation

专用消息不能用于插件

如果将自定义 API 定义为专用 API,则无法在插件中使用该消息。 了解私人消息

无法为自定义 API 的主要操作插件设置安全和不安全的配置

无法将 安全或不安全的配置 传递给自定义 API 的主作插件。

解决方法:使用插件注册工具(PRT)在PostOperation阶段注册插件,而不是将插件与自定义 API 相关联。 使用此方法,可以 像往常一样在 PostOperation 插件步骤中指定配置数据

若要使用此解决方法,必须配置自定义 API,以便在创建自定义 API 时启用 同步和异步自定义处理步骤类型 。 创建此设置后无法更改此设置。

后续步骤

使用插件注册工具创建自定义 API

另请参阅

创建和使用自定义 API
使用代码创建自定义 API
使用解决方案文件创建自定义 API
创建自己的邮件
自定义 API 表