使用.NET Core 3.1的Azure Webjob [英] Azure webjob using .NET core 3.1

查看:82
本文介绍了使用.NET Core 3.1的Azure Webjob的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用.net core 3.1编写一个天蓝色的webjob,并且遇到以下运行时异常: InvalidOperationException:%EventHubName%无法解析为值.

我的触发器如下所示: ProcessEvent([EventHubTrigger("%EventHubName%", ConsumerGroup = "%ConsumerGroupName%")] EventData eventData)

我已经在program.cs中注册了配置

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

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

有人可以建议我可能想念的东西吗?

解决方案

更新0515:

解决方法:

1.请同时添加appsettings.jsonappsettings.dev.json(请记住右键单击这些文件->选择属性->将复制到输出目录"设置为如果更新则复制")文件到您的项目中. 2个json文件应具有相同的结构(键),但值可以不同.如下所示:

我的appsettings.json文件:

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

我的appsettings.dev.json文件:

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

2.在 CustomNameResolver 类中,使用以下代码:

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.dev.json之前添加appsettings.json,因此appsettings.dev.json中的设置具有较高的优先级,它将覆盖appsettings.json中的相同键. >

3.然后运行该项目并将事件发送到appsettings.dev.json中定义的 yyeventhub2 ,然后可以发现已触发Webjob.


原始答案:

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

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

1.一些最新的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.无法在Functions.cs中以%EventHubConnectionString%格式使用eventhub命名空间连接字符串.

3.请勿使用appsettings.json中的嵌套设置.

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

5.使用%%格式时,应使用将复制到输出目录"设置为如果更新则复制"):

{     
    "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类(创建一个名为CustomNameResolver.cs的自定义类):

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());
    }
}

测试结果:

I am writing a azure webjob using .net core 3.1 and I am getting the following runtime exception: InvalidOperationException: %EventHubName% does not resolve to a value.

where my trigger looks like: ProcessEvent([EventHubTrigger("%EventHubName%", ConsumerGroup = "%ConsumerGroupName%")] EventData eventData)

I have registered the configuration in program.cs

I have added appSettings.environment.json file which contains something like:

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

Can anyone suggest what I maybe missing?

解决方案

Update 0515:

The workaround:

1.Please add both appsettings.json and appsettings.dev.json(Remember right click these files -> select properties -> set "Copy to Output Directory" as "copy if newer") files into your project. The 2 json files should have the same structure(the keys), but the value can be different. Like below:

My appsettings.json file:

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

My appsettings.dev.json file:

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

2.In CustomNameResolver class, use the code below:

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];
    }
}

note, appsettings.json should be added before appsettings.dev.json, so the settings in appsettings.dev.json has high priority which will overwrite the same keys in appsettings.json.

3.Then run the project and send events to yyeventhub2 which is defined in appsettings.dev.json, then you can find the webjob is triggered.


Original answer:

There're some limitations when use %% in the function.

As per my test, here are some notes:

1.Some latest nuget packages cannot work with eventhub trigger, you should use the below version of nuget packages:

<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 namespace connection string cannot be used in this format %EventHubConnectionString% in the Functions.cs.

3.Don't use the nested settings in appsettings.json.

4.Don't specify EventProcessorHostName and StorageContainerName in appsettings.json. The webjobs SDK automatically set them for you.

5.When use %% format, you should use Custom binding expressions to resolve the name.

The following are my code and appsettings.json:

appsettings.json(please also right click this file -> select Properties -> set "Copy to Output Directory" as "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"  
}

My NameResolver class(create a custom class named CustomNameResolver.cs):

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());
    }
}

Test result:

这篇关于使用.NET Core 3.1的Azure Webjob的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆