使用 .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.json
和 appsettings.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 中指定 EventProcessorHostName
和 StorageContainerName
。 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());
}
}
测试结果:
我正在使用 .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.json
和 appsettings.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 中指定 EventProcessorHostName
和 StorageContainerName
。 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());
}
}
测试结果: