无法让 Dataverse ServiceClient 在 Azure Function 中正常工作

问题描述 投票:0回答:1

我在 Azure Functions 应用程序(.NET 8,隔离工作线程模型)中有一组 HTTP 触发的函数,它们使用 Dataverse ServiceClient (v1.1.17) 与 Dynamics 365 集成。我遇到的问题是,当我发送多个请求时,底层的

HttpClient
会意外被处理。

起初我以为这个问题与

ServiceClient
的生命周期有关。但是,我通过将其注册为作用域和单例来测试它,但没有区别。我尝试创建一个新实例并在每次使用后将其丢弃。我什至尝试了在 GitHub 存储库CdsWeb中找到的一个“技巧”,它包装客户端并创建可重用的实例副本。

我已经在全新的最小 API 中运行了相同的代码,并且运行得很好。在循环内的控制台应用程序中运行它也是如此。当使用 k6(100 个 VU,持续 20 秒)对其进行负载测试时,会导致 1 次完成迭代和 99 次中断迭代。然而,当以最小的 API 实现时,会导致 100 次完成迭代和 0 次中断迭代。

在 Azure 中运行该函数(基于消耗)会产生相同的错误。它还定期产生

TaskCanceledException

这是最低限度的测试:

var query = new QueryExpression(entityName: "contact")
{
    TopCount = 1,
    ColumnSet = new ColumnSet("contactid", "firstname")
};

// serviceClient injected as a singleton. Access token is cached in memory and reused.
var results = await serviceClient.RetrieveMultipleAsync(query);
var contactEntity = results.Entities.SingleOrDefault();

这就是 ServiceClient 的设置方式:

// Adding it to servicecollection
services.AddSingleton<IOrganizationServiceAsync, ServiceClient>(provider =>
{
    var appSettings = provider.GetRequiredService<IOptions<AppSettings>>();
    var cache = provider.GetRequiredService<IMemoryCache>();

    var managedIdentity = new DefaultAzureCredential(new DefaultAzureCredentialOptions
    {
        // Using Managed Identity running in Azure
        ManagedIdentityClientId = appSettings.Value.ManagedIdentityClientId,
        ExcludeManagedIdentityCredential = false,

        // Using Visual Studio/VS Code credentials for local devlopment
        ExcludeVisualStudioCredential = false,
        ExcludeVisualStudioCodeCredential = false
    });
    var environment = appSettings.Value.DataverseInstanceUrl;

    return new ServiceClient(
            tokenProviderFunction: f => GetToken(environment, managedIdentity, cache),
            instanceUrl: new Uri(environment),
            useUniqueInstance: true);
});

// Getting access token and caching it for 50 minutes
async static Task<string> GetToken(string environment, DefaultAzureCredential credential, IMemoryCache cache)
{
    var accessToken = await cache.GetOrCreateAsync(environment, async (cacheEntry) =>
    {
        cacheEntry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(50);
        var token = await credential.GetTokenAsync(new TokenRequestContext([$"{environment}/.default"]));
        return token;
    });
    return accessToken.Token;
}
c# azure-functions .net-8.0 dataverse azure-functions-isolated
1个回答
0
投票

NuGet 包

Microsoft.PowerPlatform.Dataverse.Client
版本 1.1.17 基于 .NET 6.0 构建。需要注意的是,它依赖于程序集
System.Text.Json Version 7.0.0.0
,它是 .NET 7 的一部分。但是,.NET 7 在 Azure Functions 服务器上不可用。请参阅 GitHub 上的讨论Power Apps 社区论坛

一个简单的修复方法是将 Azure Function 项目基于 .NET 6 并使用 NuGet 包

Microsoft.PowerPlatform.Dataverse.Client

 版本 1.1.14 而不是最新版本。

微软计划在今年年底添加 .NET 8 支持。

© www.soinside.com 2019 - 2024. All rights reserved.