我试图从GetSection
中的注入(inject)配置中调用Startup.cs
。
值是null
,而将indexer
转换为具体节值将返回non-null
值。在我看来,GetSection
方法背后的错误还是我错了?
appsettings.json:
Program.cs:
public static void Main(string[] args)
{
var host = BuildWebHost(args);
host.Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
Startup.cs:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
var mySection = this.Configuration.GetSection("MyConfig");
var myVal = this.Configuration["MyConfig:ConfigA"];
最佳答案
我首先检查了JsonConfigurationProvider.cs
的1.1.1和2.x之间是否有任何变化,该内部代码最终从您的JSON文件构造了可检索的值。对该代码或其他任何最终由this.Configuration.GetSection("MyConfig");
调用的代码都没有任何更改。
检索值的方式是Configuration
将按照代码中定义的相反顺序在每个配置提供程序中寻找关键的MyConfig
,直到找到一个值。在您的示例中,Webhost.CreateDefaultBuilder()
(see here)中提供了提供程序(json,环境变量,命令行参数)。
查看JsonConfigurationFileParser.cs的代码,它将为键和值(但仅针对原始值)构建Dictionary<string, string>
。也就是说,没有存储MyConfig
的键(在这个级别上它是一个对象),但是将存在MyConfig:ConfigA
的键,并且数组值看起来像MyConfig:ConfigA:0
,MyConfig:ConfigA:1
等。
最后,您会发现的Configuration.GetSection("MyConfig")
always returns you a newly constructed永远不会为无效,最糟糕的是ConfigurationSection
的Value
属性。
因此,当您使用Intellisense将鼠标悬停在null
上并查看ConfigurationSection
属性时,会发生以下情况:已搜索了每个配置提供程序,但都没有找到具有原始值转换为字符串以返回的“MyConfig”键的键。
您至少需要致电:services.Configure<MyConfigOptions>(configuration.GetSection("MyConfig"));
services.AddSingleton(cfg => cfg.GetService<IOptions<MyConfigOptions>>().Value);
将其作为C#对象注入(inject)整个应用程序。否则,请使用冒号Value
分隔符语法或["MyConfig:ConfigA"]
调用单个值,这是多余的,但说明仅用于检索基元。
为了绑定(bind)到C#对象并注入(inject)它们,我创建了以下扩展方法:public static class IServiceCollectionExtensions
{
public static IServiceCollection AddConfigOptions<TOptions>(this IServiceCollection services,
IConfiguration configuration, string section) where TOptions : class, new()
{
services.Configure<TOptions>(configuration.GetSection(section));
services.AddSingleton(cfg => cfg.GetService<IOptions<TOptions>>().Value);
return services;
}
}
可以这样称呼:public class Startup
{
public Startup(IConfiguration configuration) => Configuration = configuration;
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddConfigOptions<EmailOptions>(Configuration, "Email")
并像这样注入(inject):public class EmailSender : IEmailSender
{
private EmailOptions _emailOptions;
public EmailSender(EmailOptions options) => _emailOptions = options;
关于c# - ASP.net Core 2.0预览版配置中的appsettings.json null,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45030383/