我试图从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.cs1.1.12.x之间是否有任何变化,该内部代码最终从您的JSON文件构造了可检索的值。对该代码或其他任何最终由this.Configuration.GetSection("MyConfig");调用的代码都没有任何更改。

检索值的方式是Configuration将按照代码中定义的相反顺序在每个配置提供程序中寻找关键的MyConfig,直到找到一个值。在您的示例中,Webhost.CreateDefaultBuilder() (see here)中提供了提供程序(json,环境变量,命令行参数)。

查看JsonConfigurationFileParser.cs的代码,它将为键和值(但仅针对原始值)构建Dictionary<string, string>。也就是说,没有存储MyConfig的键(在这个级别上它是一个对象),但是将存在MyConfig:ConfigA的键,并且数组值看起来像MyConfig:ConfigA:0MyConfig:ConfigA:1等。

最后,您会发现Configuration.GetSection("MyConfig") always returns you a newly constructed永远不会为无效,最糟糕的是ConfigurationSectionValue属性。

因此,当您使用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/

10-10 17:58