通过


后台操作(预览)

[本文是预发行文档,可能会有所更改。]

使用后台操作来发送由 Dataverse 异步处理的请求。 如果您不想在请求运行时保持连接,后台操作非常有用。

后台操作完成后,您可以通过以下两种方式之一收到通知:

可以通过以下两种方式之一检索后台操作的结果:

若要在后台运行请求,请将该操作定义为自定义 API。 有关详细信息,请参阅 创建和使用自定义 API检索有关自定义 API 的数据

自定义 API 使用插件来执行数据操作。 与所有 Dataverse 插件一样,这些插件的执行超时为两分钟。 异步发送请求不提供更多的执行时间。

所需权限

若要执行后台操作,发起操作的用户必须具有对 backgroundoperations 表中读取和写入的访问权限。 将 prvReadbackgroundoperationprvWritebackgroundoperation 权限分配给用户以授予此访问权限。

了解如何编辑安全角色

请求异步处理

可以使用 SDK for .NET 或 Dataverse Web API 在后台运行异步请求。

本文中的示例使用名为 sample_ExportDataUsingFetchXmlToAnnotation 的自定义 API。 有关此自定义 API 的详细信息,请参阅 示例:ExportDataUsingFetchXmlToAnnotation 自定义 API

使用 ExecuteBackgroundOperation 消息。

SDK 没有 ExecuteBackgroundOperation 请求和响应类。 在添加这些类之前,请按照 使用 .NET SDK 进行消息处理 中的描述,使用基本 OrganizationRequestOrganizationResponse 类。

下表描述了消息的 ExecuteBackgroundOperation 输入参数。

Name 类型 Description
Request OrganizationRequest (必需)包含要异步处理的请求。 请求的 Dataverse 消息必须作为自定义 API 实现。
CallbackUri 字符串 (可选)Dataverse 在作完成后向此 URL 发送 POST HTTP 请求。

下表描述了消息的 ExecuteBackgroundOperation 输出参数。

Name 类型 Description
BackgroundOperationId Guid 标识您可用于监视或取消请求处理的背景操作表行。
Location 字符串 标识您可用于检索请求状态或取消请求的状态监视器资源 URL。

以下静态方法使用 ExecuteBackgroundOperationsample_ExportDataUsingFetchXmlToAnnotation 自定义 API。

static void SendRequestAsynchronously(IOrganizationService service)
{
    //Create a request for message defined as a custom API to run in the background
    var asyncRequest = new OrganizationRequest("sample_ExportDataUsingFetchXmlToAnnotation")
    {
        Parameters =
        {
            {"FetchXml",  @"<fetch>
                                <entity name='account'>
                                    <attribute name='accountid'/>
                                    <attribute name='name'/>  
                                </entity>
                            </fetch>" }
        }
    };

    //Create a request to execute the message in the background
    var request = new OrganizationRequest("ExecuteBackgroundOperation")
    {
        Parameters =
        {
            {"Request", asyncRequest }
        }
    };

    //Execute the background operation request
    var response = service.Execute(request);

    Console.WriteLine($"BackgroundOperationId: {response["BackgroundOperationId"]}");
    Console.WriteLine($"Location: {response["Location"]}");
}

输出:

BackgroundOperationId: <backgroundoperationid value>
Location: [Organization URI]/api/backgroundoperation/<backgroundoperationid value>

详细了解 IOrganizationService 接口 以及如何 将消息与 SDK for .NET 配合使用

管理后台操作

当您发送后台处理请求时,响应结果包含两个值,这些值表示可用于监视或取消后台操作的不同方法。

  • 使用表中行backgroundoperations的 ID 检索或更新表中的数据:

  • 使用表示状态监控资源的Location URL来轮询和取消后台操作。

    重要

    状态监视器资源不是 Web API backgroundoperation EntityType 资源。

    URL Example
    状态监视器资源 [Organization URI]/api/backgroundoperation/<backgroundoperationid value>
    backgroundoperation EntityType 资源 [Organization URI]/api/data/v9.2/backgroundoperations(<backgroundoperationid value>)

    状态监视器资源不是 Dataverse Web API 的一部分。 请注意,URL 不包含 /data/v9.2/。 状态监视器资源仅支持 GET 和 DELETE 操作,其行为与 Web API backgroundoperation EntityType 资源不相同。

查询后台作表或状态监视器资源以检查请求通常称为 状态轮询。 避免过度轮询,因为它可能会对性能产生负面影响。 如果需要,请每隔一分钟或多分钟轮询。

后台操作表

背景操作表包含有关异步处理请求的信息。 此表具有逻辑名称 backgroundoperation 和实体集名称 backgroundoperations了解后台操作实体类型 (backgroundoperation EntityType)

下表描述了可用于管理后台作业状态的列。

显示名称
架构名称
逻辑名称
类型 Description
后台操作
BackgroundOperationId
backgroundoperationid
唯一标识符 主键
状态
StateCode
backgroundoperationstatecode
选择列表 后台操作的状态

选项:
- 值: 0,标签: 就绪
- 值: 2,标签: 已锁定
- 值: 3,标签: 已完成
状态描述
StatusCode
backgroundoperationstatuscode
选择列表 后台操作的状态

选项:
- 值: 0,标签: 等待资源 (状态:就绪)
- 值: 20,标签: 正在进行 (状态:已锁定)
- 值: 22,标签: 取消 (状态:已锁定)
- 值: 30,标签: 成功 (状态:已完成)
- 值: 31,标签: 失败 (状态:已完成)
- 值: 32,标签: 已取消 (状态:已完成)
Name
Name
name
String UniqueName用于后台操作的定制 API
显示名称
DisplayName
displayname
String DisplayName用于后台操作的自定义 API
输入参数
InputParameters
inputparameters
备忘录 用于启动后台操作的输入参数

此字符串是一个包含 KeyValue 的 JSON 序列化数组。
输出参数
OutputParameters
outputparameters
备忘录 后台操作的响应

此字符串是 KeyValue 组成的 JSON 序列化数组。
开始时间
StartTime
starttime
日期时间 后台操作开始执行时
结束时间
EndTime
endtime
日期时间 后台操作执行完毕后
重试计数
RetryCount
retrycount
整数 重试后台操作的次数
错误代码
ErrorCode
errorcode
整数 如果后台操作失败,错误代码

如果错误来自 Dataverse,则它具有一个整数值,该值对应于 Web 服务错误代码中列出的代码之一。 如果错误不是来自 Dataverse,则该值设置为零。
错误消息
ErrorMessage
errormessage
备忘录 如果后台操作失败,错误信息
运行方式
RunAs
runas
String 用于执行后台操作的systemusersystemuserid
创建日期
CreatedOn
createdon
日期时间 创建记录时
生存时间
TTLInSeconds
ttlinseconds
整数 生存时间(以秒为单位),之后会自动删除记录;默认值为 90 天

轮询后台操作表

请确保在查询中包含这些列:

  • name
  • backgroundoperationstatecode
  • backgroundoperationstatuscode
  • outputparameters
  • errorcode
  • errormessage

轮询表的方式取决于使用的是 SDK 还是 Web API。

static void PollBackgroundOperationRequest(IOrganizationService service, Guid backgroundOperationId)
{
    // List of columns that will help to get status, output and error details if any
    var columnSet = new ColumnSet(
        "name",
        "backgroundoperationstatecode",
        "backgroundoperationstatuscode",
        "outputparameters",
        "errorcode",
        "errormessage");

    try
    {
        // Get the entity with all the required columns
        var backgroundOperation = service.Retrieve("backgroundoperation", backgroundOperationId, columnSet);

        Console.WriteLine($"Name: {backgroundOperation["name"]}");
        Console.WriteLine($"State Code: {backgroundOperation.FormattedValues["backgroundoperationstatecode"]}");
        Console.WriteLine($"Status Code: {backgroundOperation.FormattedValues["backgroundoperationstatuscode"]}");
        Console.WriteLine($"Output Parameters:");

        // Deserialize the Output Parameters into KeyValuePair<string, string>
        List<KeyValuePair<string, string>>? output = 
            System.Text.Json.JsonSerializer
            .Deserialize<List<KeyValuePair<string, string>>>((string)backgroundOperation["outputparameters"]);

        output.ForEach(x => {
            Console.WriteLine($"\t{x.Key}: {x.Value}");
        });

        Console.WriteLine($"Error Code: {backgroundOperation.GetAttributeValue<string>("errorcode")}");
        Console.WriteLine($"Error Message: {backgroundOperation.GetAttributeValue<string>("errormessage")}");
    }
    // Catch Dataverse errors
    catch (FaultException<OrganizationServiceFault> ex)
    {
        Console.WriteLine($"ErrorCode:{ex.Detail.ErrorCode}");
        Console.WriteLine($"Message:{ex.Detail.Message}");
    }
    // Catch other errors
    catch (Exception error)
    {
        Console.WriteLine($"Some other error occurred: '{error.Message}'");
    }
}

等待输出:

Name: sample_ExportDataUsingFetchXmlToAnnotation
State Code: Locked
Status Code:  In Progress
Output Parameters:  
Error Code:  
Error Message:  

完成输出:

Name: sample_ExportDataUsingFetchXmlToAnnotation
State Code: Completed
Status Code:  Succeeded
Output Parameters:
        AnnotationId: {value}
Error Code:  
Error Message:  

错误输出:

Name: sample_ExportDataUsingFetchXmlToAnnotation
State Code: Completed
Status Code:  Failed
Output Parameters: 
Error Code:  -2147187707
Error Message:  Access is denied.

如果平台生成错误,则它具有一个整数值,该值对应于 Web 服务错误代码中列出的代码之一。 如果平台不生成错误,请将其值设置为零。

找不到 ID:

ErrorCode:-2147185406
Message:The HTTP status code of the response was not expected (404).

Status: 404
Response:
{"error":{"message":"Could not find item '110eaa68-db17-4115-ad74-d185823fc089'.","details":[{"message":"\r\nErrors : [\r\n  \"Resource Not Found. Learn more: https://aka.ms/cosmosdb-tsg-not-found\"\r\n]\r\n"}]}}

轮询状态监视器资源

可以使用 GET 请求轮询状态监视器资源。 此请求返回后台操作的状态。 如果操作已完成,则提供自定义 API 的输出。 如果在执行过程中发生错误,则会收到错误消息和代码。

将请求发送到原始请求在Location响应标头中返回的状态监视器资源 URL。

请求:

GET [Organization URI]/api/backgroundoperation/{backgroundoperationid}
Content-Type: application/json  

响应:

HTTP/1.1 200 OK
Content-Type: application/json

{
  backgroundOperationErrorCode: {INT},
  backgroundOperationErrorMessage: {string},
  backgroundOperationStateCode: {INT},
  backgroundOperationStatusCode: {INT},
  outputParam1: {value},
  outputParam2: {value},
  outputParam3: {value},
}

仅当发生错误时,响应才包括 backgroundOperationErrorCodebackgroundOperationErrorMessage 值。 仅当操作成功完成时,它才包括输出参数。

状态监视器资源不提供标签。

接收结果通知

若要在后台操作完成时获取通知,可以 包含请求的回调 URL订阅 OnBackgroundOperationComplete 事件

请求电话回拨

可以在请求中指定 URL,以在作完成后接收回调。 Dataverse 使用此 URL 发送具有以下有效负载的 POST 请求:

{
    "location": "< status monitor resource URL >",
    "backgroundOperationId": "{GUID}",
    "backgroundOperationStateCode": {INT},
    "backgroundOperationStatusCode": {INT},
    "backgroundOperationErrorCode": {INT},
    "backgroundOperationErrorMessage": {string},
}

backgroundOperationErrorCode 并且 backgroundOperationErrorMessage 仅在发生错误时包含。

回调有效负载不包含任何输出参数。 接收回调的站点必须使用状态监视器资源 URL 发送经过身份验证的 GET 请求才能获取结果。

如果 URL 需要身份验证,则必须是自给自足 的共享访问签名 (SAS) URL。 不能再包含任何用来提供 API 密钥或令牌进行身份验证的标头。

若要测试回调 URL,请考虑使用 类似于 webhook.site 的网站。

请求回调的方式取决于使用的是 SDK 还是 Web API。 以下示例通过使用 webhook 向 webhook.site 发送请求以进行测试。

通过使用 SDK,将 ExecuteBackgroundOperation.CallbackUri 参数设置为 URL 以发送请求。

static void SendRequestAsynchronouslyWithCallback(IOrganizationService service)
{
    //Create a request for message defined as a custom API to run in the background
    var asyncRequest = new OrganizationRequest("sample_ExportDataUsingFetchXmlToAnnotation")
    {
        Parameters =
        {
            {"FetchXml",  @"<fetch>
                                <entity name='account'>
                                    <attribute name='accountid'/>
                                    <attribute name='name'/>  
                                </entity>
                            </fetch>" }
        }
    };

    //Create a request to execute the message in the background
    var request = new OrganizationRequest("ExecuteBackgroundOperation")
    {
        Parameters =
        {
            {"Request", asyncRequest },
            // Request a callback
            {"CallbackUri", "https://webhook.site/<id>" }
        }
    };

    //Execute the background operation request
    var response = service.Execute(request);

    Console.WriteLine($"BackgroundOperationId: {response["BackgroundOperationId"]}");
    Console.WriteLine($"Location: {response["Location"]}");
}

订阅 OnBackgroundOperationComplete 事件

OnBackgroundOperationComplete 消息上注册一个步骤,可以在后台操作完成时收到通知。 此消息是仅支持异步步骤注册的自定义 API。 它是使用自定义 API 来表示 业务事件的消息类型的示例。

顾名思义,每当后台操作完成时,都会触发 OnBackgroundOperationComplete 事件。 在此事件上注册异步步骤时,可以在插件中执行任何类型的逻辑,或将数据转发到 Azure 服务或 Webhook。 有关详细信息,请参见:

下表描述了消息的 OnBackgroundOperationComplete 输入和输出参数。

输入参数:

Name 类型 Description
PayloadType 整数 后台操作完成时发送到回调 URI 的响应类型。 后台操作始终为零。

此字段是内部字段,不应更新。
LocationUrl String 位置 URL
BackgroundOperationId Guid 后台操作的 ID

输出参数:

Name 类型 Description
OperationName String 操作名称
BackgroundOperationStateCode 整数 后台操作状态代码
BackgroundOperationStatusCode 整数 后台操作状态代码

配置 OnBackgroundOperationComplete 消息,如说明中所示,以 注册插件。 将消息名称设置为 OnBackgroundOperationComplete. 将 Auto Delete 设置为 true,以便自动删除 系统作业(AsyncOperation) 记录。

取消后台操作

如果您发起的后台操作尚未启动,可以取消。

  • 如果操作没有启动,Dataverse 不会执行该操作。
  • 如果操作已启动,Dataverse 不会停止该操作。
  • 如果在执行取消的后台作期间发生错误,Dataverse 不会重试。
  • 如果操作已经完成,则会出现以下错误:Canceling background operation is not allowed after it is in terminal state.

可以通过以下两种方式之一取消后台操作:

通过更新 backgroundoperations 来取消后台操作

更新表中的 backgroundoperations 行,将设置为 backgroundoperationstatecode2已锁定”和 backgroundoperationstatuscode22取消”。

更新 backgroundoperations 表的方式取决于使用的是 SDK 还是 Web API。

static void CancelBackgroundOperationRequest(
    IOrganizationService service, 
    Guid backgroundOperationId)
{
    var backgroundOperation = new Entity(
        entityName: "backgroundoperation", 
        id: backgroundOperationId)
    { 
        Attributes =
        {
            //Set state as Locked
            {"backgroundoperationstatecode", new OptionSetValue(2) },
            //Set status as Cancelling
            {"backgroundoperationstatuscode", new OptionSetValue(22) }
        }            
    }; 

    service.Update(backgroundOperation);
}

将 DELETE 请求发送到状态监视器资源

您还可以通过向状态监视器资源发送 DELETE 请求来取消后台操作。

请求:

DELETE [Organization URI]/api/backgroundoperation/{backgroundoperationid}

响应:

HTTP/1.1 200 Ok

{
    backgroundOperationStateCode: 2,
    backgroundOperationStatusCode: 22
}

重试

如果在执行请求期间发生错误,则系统最多重试三次。 这些重试使用 指数退避策略