ASP.net Core 2.0 Preview配置中的appsettings.json获取null [英] appsettings.json in ASP.net Core 2.0 Preview configuration GetSection null
问题描述
我试图从Startup.cs
中的注入配置中调用GetSection
.
值是null
,而indexer
到具体节的值则返回non-null
值.在我看来,GetSection
方法背后的错误还是我错了?
appsettings.json:
{"MyConfig":{ "ConfigA":"valueA", "ConfigB":"valueB"}}
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"];
我首先检查一下 2.x of JsonConfigurationProvider.cs
,这是最终从JSON文件构造可检索值的内部代码.对该代码或您最终this.Configuration.GetSection("MyConfig");
最终调用的其他任何代码都没有任何更改.
检索值的工作方式是Configuration
将按照代码中的定义以相反的顺序在每个配置提供程序 中寻找密钥MyConfig
,直到找到一个值为止.在您的示例中,在Webhost.CreateDefaultBuilder()
JsonConfigurationFileParser.cs ,它为键和值(,但仅对于原始值)构建了Dictionary<string, string>
.也就是说,没有存储MyConfig
的键(在这个级别上它是一个对象),但是会有MyConfig:ConfigA
的键,并且数组值看起来像MyConfig:ConfigA:0
,MyConfig:ConfigA:1
等.>
最后,您会发现 您至少需要致电: 将其作为C#对象注入整个应用程序.否则,请使用冒号 要绑定到C#对象并注入它们,我创建了以下扩展方法: 可以这样称呼: 并像这样注入: I was trying to call appsettings.json: { "MyConfig": {
"ConfigA": "valueA",
"ConfigB": "valueB" } } Program.cs: Startup.cs:
I first checked to see if there were any changes between 1.1.1 and 2.x of The way retrieving values works is that the Looking at the code for JsonConfigurationFileParser.cs, it builds a Lastly, you will find that So what happens when you hover over a You will at the very least need to call: to have it injected throughout your app as a C# object. Otherwise, call individual values with the colon To bind to C# objects and inject them, I created the following extension method: which can be called like this: and injected like this:
这篇关于ASP.net Core 2.0 Preview配置中的appsettings.json获取null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!Configuration.GetSection("MyConfig")
services.Configure<MyConfigOptions>(configuration.GetSection("MyConfig"));
services.AddSingleton(cfg => cfg.GetService<IOptions<MyConfigOptions>>().Value);
["MyConfig:ConfigA"]
分隔符语法或var mySection = this.Configuration.GetSection("MyConfig")["ConfigA"];
调用单个值,这是多余的,但说明仅用于检索基元.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")
public class EmailSender : IEmailSender
{
private EmailOptions _emailOptions;
public EmailSender(EmailOptions options) => _emailOptions = options;
GetSection
from injected configuration in the Startup.cs
.
The Value was null
, while indexer
to a concrete section value returns non-null
value. It seems to me a bug behind the GetSection
method or I am wrong with it?
public static void Main(string[] args)
{
var host = BuildWebHost(args);
host.Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
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
, the internal code that ultimately constructs retrievable values from your JSON file. There were no changes to this or any of the other code that ultimately gets called by your this.Configuration.GetSection("MyConfig");
.Configuration
will look for your key MyConfig
in each config provider in reverse order as defined in code until a value is found. In your example, providers (json, envionment variables, command line args) are provided within Webhost.CreateDefaultBuilder()
(see here).Dictionary<string, string>
for keys and values, but only for primitive values. That is, no key is stored for MyConfig
(at this level it is an object), but there will be a key for MyConfig:ConfigA
, and array values would look like MyConfig:ConfigA:0
, MyConfig:ConfigA:1
, etc.Configuration.GetSection("MyConfig")
always returns you a newly constructed ConfigurationSection
that is never null, and at the very worst will have a Value
property of null
.ConfigurationSection
with Intellisense and look at the Value
property is that every config provider had been searched and none was found to have a key of "MyConfig" with a primitive value converted to string to return. services.Configure<MyConfigOptions>(configuration.GetSection("MyConfig"));
services.AddSingleton(cfg => cfg.GetService<IOptions<MyConfigOptions>>().Value);
["MyConfig:ConfigA"]
separator syntax or with var mySection = this.Configuration.GetSection("MyConfig")["ConfigA"];
, which is redundant but illustrates it is only used to retrieve primitives.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")
public class EmailSender : IEmailSender
{
private EmailOptions _emailOptions;
public EmailSender(EmailOptions options) => _emailOptions = options;