使用 .NET 核心 3.1 的 Azure 网络作业

Azure webjob using .NET core 3.1

我正在使用 .net core 3.1 编写一个 azure webjob,我收到以下运行时异常: InvalidOperationException:%EventHubName% 未解析为值。

我的触发器看起来像: ProcessEvent([EventHubTrigger("%EventHubName%", ConsumerGroup = "%ConsumerGroupName%")] EventData eventData)

我在program.cs

注册了配置

我添加了 appSettings.environment.json 文件,其中包含如下内容:

"EventHubConfig": { "EventHubConnectionString": "..", "EventHubName": "..", "EventProcessorHostName": "..", "ConsumerGroupName": "..", "StorageConnectionString": "..", "StorageContainerName": ".." },

任何人都可以提出我可能遗漏的建议吗?

使用%%XXX%%是读取设置的正确方法。

当您在本地开发您的应用程序时,请在 local.settings.json 文件中搜索这些变量。

示例:

{
    "EventHubName": "myeventhubname"
}

如果您部署在 Azure 上,则需要将变量添加到应用程序设置 Read more

更新 0515:

解决方法:

1.Please 同时添加 appsettings.jsonappsettings.dev.json(记住右键单击这些文件 -> select 属性 -> 将 "Copy to Output Directory" 设置为 "copy if newer") 文件到您的项目中。 2 json 文件应该具有相同的结构(键),但值可以不同。如下所示:

我的appsettings.json文件:

{
  "AzureWebJobsStorage": "xxxxx",
  "EventHubConnectionString": "xxxx",
  "EventHubName": "yyeventhub1",
  "ConsumerGroupName": "cg1"
}

我的 appsettings.dev.json 文件:

   {
      "AzureWebJobsStorage": "xxxxx",
      "EventHubConnectionString": "xxxx",
      "EventHubName": "yyeventhub2",
      "ConsumerGroupName": "hub2cg"
    }

2.In CustomNameResolver class,使用下面的代码:

public class CustomNameResolver : INameResolver
{
    public string Resolve(string name)
    {
        var config = new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
        .AddJsonFile("appsettings.dev.json", optional: true, reloadOnChange: true)
        .AddEnvironmentVariables()
        .Build();

        return config[name];
    }
}

注意,appsettings.json应该在appsettings.dev.json之前加上,所以appsettings.dev.json里面的设置优先级高,会覆盖相同的key在 appsettings.json.

3.Then 运行 项目,发送事件到appsettings.dev.json中定义的yyeventhub2,然后可以发现webjob被触发了.


原回答:

在函数中使用 %% 有一些限制。

根据我的测试,这里有一些注意事项:

1.Some 最新的 nuget 包无法与 eventhub 触发器一起使用,您应该使用以下版本的 nuget 包:

<ItemGroup>
    <PackageReference Include="Microsoft.Azure.WebJobs.Extensions" Version="3.0.0" />
    <PackageReference Include="Microsoft.Azure.WebJobs.Extensions.EventHubs" Version="4.1.1" />
    <PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Storage" Version="3.0.10" />
    <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.1.4" />
    <PackageReference Include="System.Configuration.ConfigurationManager" Version="4.7.0" />
  </ItemGroup>

2.The eventhub 命名空间连接字符串不能在 Functions.cs.

这种格式中使用 %EventHubConnectionString%

3.Don不使用 appsettings.json 中的嵌套设置。

4.Don未在 appsettings.json 中指定 EventProcessorHostNameStorageContainerName。 webjobs SDK 会自动为您设置它们。

5.When使用%%格式,你应该使用Custom binding expressions来解析名称。

以下是我的代码和appsettings.json:

appsettings.json(请同时右键单击此文件 -> select 属性 -> 将 "Copy to Output Directory" 设置为 "Copy if newer") :

{     
    "AzureWebJobsStorage": "DefaultEndpointsProtocol=https;AccountName=xx;AccountKey=xx;BlobEndpoint=https://xxx.blob.core.windows.net/;TableEndpoint=https://xxx.table.core.windows.net/;QueueEndpoint=https://xxx.queue.core.windows.net/;FileEndpoint=https://xxx.file.core.windows.net/",
    "EventHubConnectionString": "Endpoint=sb://xxx.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=xxx",
    "EventHubName": "xxx",
    "ConsumerGroupName": "xxx"  
}

我的 NameResolver class(创建一个名为 CustomNameResolver.cs 的自定义 class)

public class CustomNameResolver : INameResolver
{
    public string Resolve(string name)
    {
        var config = new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
        //.AddJsonFile($"appsettings.{environment}.json", optional: true, reloadOnChange: true)
        .AddEnvironmentVariables()
        .Build();

        return config[name];
    }
}

Program.cs:

class Program
{     

    static void Main(string[] args)
    {
        var builder = new HostBuilder();
        var resolver = new CustomNameResolver();

        builder.ConfigureWebJobs(b =>
        {
            b.AddAzureStorageCoreServices();
            b.AddAzureStorage();
            b.AddEventHubs();
        });
        builder.ConfigureLogging((context, b) =>
        {
            b.AddConsole();
        });          

        builder.ConfigureServices(s => s.AddSingleton<INameResolver>(resolver));

        var host = builder.Build();
        using (host)
        {
            host.Run();
        }
    }
}

Functions.cs:

public class Functions
{
    public static void ProcessEvent([EventHubTrigger("%EventHubName%", Connection = "EventHubConnectionString",ConsumerGroup = "%ConsumerGroupName%")] EventData eventData, ILogger logger)
    {
        logger.LogInformation("it is triggered!" + DateTime.Now.ToLongTimeString());
    }
}

测试结果: