如何在 Azure Functions 4.x (.NET 8) 中使用多重响应技术并在 C# 代码中进行多个绑定?

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

.NET 8.0.403,函数 4.0.6280

使用 Microsoft 的多重响应技术,我明白了

异常:System.InvalidOperationException:不允许同步操作。改为调用 WriteAsync 或将 AllowSynchronousIO 设置为 true

该错误发生在 Windows 和 MacOS 上的两个独立的 VS Code 环境中。上传到 Azure 时也会出错。

我已阅读“解决方法”,但更愿意修复代码。

这是我尝试过的:

有问题的行是

response.WriteString(message);
,所以我将其更改为
await response.WriteStringAsync(message);
并更改了功能...

来自:

[Function("HttpExample")]
public static MultiResponse Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestData req,
    FunctionContext executionContext)
{...}

至:

[Function("HttpExample")]
public static async Task<MultiResponse> Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestData req,
    FunctionContext executionContext)
{...}

这有效...但接下来我想添加一个输入绑定。于是我又改成了:

[Function("HttpExample")]
public static async Task<MultiResponse> Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestData req,
    [CosmosDBInput(
         databaseName: "my-database",
         containerName: "my-container",
         Id = "f3ac2913-85c4-4066-a5e9-1c68d1fd33e9",
         PartitionKey = "f3ac2913-85c4-4066-a5e9-1c68d1fd33e9",
         Connection = "CosmosDbConnectionSetting")] MyDocument inputDocument,
         FunctionContext executionContext)
{...}

这引发了以下错误:

[2024-10-23T20:57:51.153Z] Executed 'Functions.HttpExample' (Failed, Id=487a5679-088d-4c2d-b804-f6415fdb99b2, Duration=1094ms)
[2024-10-23T20:57:51.153Z] System.Private.CoreLib: Exception while executing function: Functions.HttpExample. System.Private.CoreLib: Result: Failure
[2024-10-23T20:57:51.153Z] Exception: IFeatureCollection has been disposed.
[2024-10-23T20:57:51.153Z] Object name: 'Collection'.
[2024-10-23T20:57:51.153Z] Stack:    at Microsoft.AspNetCore.Http.Features.FeatureReferences`1.ThrowContextDisposed()
[2024-10-23T20:57:51.153Z]    at Microsoft.AspNetCore.Http.Features.FeatureReferences`1.ContextDisposed()

据我所知,这意味着

HttpContext
被过早处理,我的阅读使我相信非静态类/函数会解决这个问题,尽管它对于这种情况来说并不好。

所以我将父类和函数更改为:

[Function("HttpExample")]
public async Task<MultiResponse> Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestData req,
    [CosmosDBInput(
         databaseName: "my-database",
         containerName: "my-container",
         Id = "f3ac2913-85c4-4066-a5e9-1c68d1fd33e9",
         PartitionKey = "f3ac2913-85c4-4066-a5e9-1c68d1fd33e9",
         Connection = "CosmosDbConnectionSetting")] MyDocument inputDocument,
         FunctionContext executionContext)
{...}

但这会引发同样的错误。我准备放弃并使用 Cosmos DB SDK 而不是绑定。这不是我想做的,因为这个项目是为了帮助我理解和实现 Azure Functions。

最后一个问题:

  1. 还有其他人经历过 Microsoft 的 example 的初始错误吗?
  2. 是否有更简单的方法来通过多重响应技术应用输入绑定?
asynchronous azure-functions static azure-cosmosdb
1个回答
0
投票

异常:IFeatureCollection 已被处置。对象名称:“集合”。堆: Microsoft.AspNetCore.Http.Features.FeatureReferences1.ThrowContextDispose() Microsoft.AspNetCore.Http.Features.FeatureReferences`1.ContextDispose()

  • 为了消除此错误并成功执行您的函数,请将 program.cs
     文件中的 
    ConfigureFunctionsWebApplication()
     替换为 
    ConfigureFunctionsWorkerDefaults() 并删除与其关联的包。我相信错误来自ConfigureFunctionsWebApplication()。您需要在 .csproj 文件中提供包。
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

var host = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults()
    .ConfigureServices(services => {
        services.AddApplicationInsightsTelemetryWorkerService();
        services.ConfigureFunctionsApplicationInsights();
    })
    .Build();

host.Run();
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <AzureFunctionsVersion>v4</AzureFunctionsVersion>
    <OutputType>Exe</OutputType>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <RootNamespace>_79120285</RootNamespace>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.ApplicationInsights.WorkerService" Version="2.22.0" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker" Version="2.0.0-preview2" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" Version="2.0.0-preview2" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.CosmosDB" Version="4.11.0" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.2.0" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="2.0.0-preview2" />
  </ItemGroup>
  <ItemGroup>
    <None Update="host.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="local.settings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <CopyToPublishDirectory>Never</CopyToPublishDirectory>
    </None>
  </ItemGroup>
  <ItemGroup>
    <Using Include="System.Threading.ExecutionContext" Alias="ExecutionContext" />
  </ItemGroup>
</Project>
  • 如果您想在函数中集成 ASP .NET Core,请在代码中使用 ConfigureFunctionsWebApplication(),或者使用 ConfigureFunctionsWorkerDefaults()

  • 我有给定的代码,其中我使用输入绑定从容器读取文档并使用输出绑定写入另一个容器。

using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;
using Microsoft.Azure.Functions.Worker.Http;
using System.Net;

namespace Company.Function
{
    public class HttpExample
    {
        private readonly ILogger<HttpExample> logger;

        public HttpExample(ILogger<HttpExample> _logger)
        {
            logger = _logger;
        }

        [Function("HttpExample")]
        public async Task<MultiResponse> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestData req,
        [CosmosDBInput(
            databaseName: "my-database",
            containerName: "my-container",
            Id = "{query.id}", 
            PartitionKey = "{query.partitionKey}",
            Connection = "CosmosDbConnectionSetting")] MyDocument inputDocument,
        FunctionContext executionContext)
        {
            var logger = executionContext.GetLogger("HttpExample");
            logger.LogInformation("C# HTTP trigger function processed a request.");

            var message = inputDocument != null 
                ? $"Document found: {inputDocument.message}"
                : "No document found.";

            var response = req.CreateResponse(HttpStatusCode.OK);
            response.Headers.Add("Content-Type", "text/plain; charset=utf-8");
            await response.WriteStringAsync(message);

            return new MultiResponse()
            {
                Document = new MyDocument
                {
                    id = Guid.NewGuid().ToString(),
                    message = message
                },
                HttpResponse = response
            };
        }
    }

    public class MultiResponse
    {
        [CosmosDBOutput("my-database", "OutputBindingContainer",
            Connection = "CosmosDbConnectionSetting", CreateIfNotExists = true)]
        public MyDocument? Document { get; set; }
        public HttpResponseData? HttpResponse { get; set; }
    }

    public class MyDocument
    {
        public string? id { get; set; }
        public string? message { get; set; }
    }
}
  • 通过进行上述更改,您可以获得预期的响应。
Azure Functions Core Tools
Core Tools Version:       4.0.6280 Commit hash: N/A +421f0144b42047aa289ce691dc6db4fc8b6143e6 (64-bit)
Function Runtime Version: 4.834.3.22875

[2024-10-24T07:45:58.348Z] Found C:\Users\******\79120285.csproj. Using for user secrets file configuration.
[2024-10-24T07:46:00.474Z] Worker process started and initialized.

Functions:

        HttpExample: [GET,POST] http://localhost:7071/api/HttpExample

For detailed output, run func with --verbose flag.
[2024-10-24T07:46:05.426Z] Host lock lease acquired by instance ID '0000000000000000000000000D2022A4'.
[2024-10-24T07:46:10.334Z] Executing 'Functions.HttpExample' (Reason='This function was programmatically called via the host APIs.', Id=c2bbb183-b62e-4301-9253-d275ad061c21)
[2024-10-24T07:46:14.671Z] C# HTTP trigger function processed a request.
[2024-10-24T07:46:19.162Z] Executed 'Functions.HttpExample' (Succeeded, Id=c2bbb183-b62e-4301-9253-d275ad061c21, Duration=8847ms)

enter image description here

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