Azure webjob using .NET core 3.1

三世轮回 提交于 2020-05-17 06:05:33

问题


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?


回答1:


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:




回答2:


Using %%XXX%% is the correct way to read settings.

When you are developing locally your app search for those variable in the local.settings.json file.

Example :

{
    "EventHubName": "myeventhubname"
}

If you deployed on Azure you need to add variables to the Applications Settings Read more



来源:https://stackoverflow.com/questions/61772846/azure-webjob-using-net-core-3-1

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!