【问题标题】:Why Startup's IConfigurationRoot is null?为什么 Startup 的 IConfigurationRoot 为空?
【发布时间】:2016-12-01 18:16:09
【问题描述】:

我正在尝试将命令行参数传递给Startup 类。按照this 的例子,我修改了我的Program 类,它看起来像这样:

        var builder = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("generalsettings.json", optional: false, reloadOnChange: true)
            .AddEnvironmentVariables(prefix: "ASPNETCORE_")
            .AddCommandLine(args);  
        var config = builder.Build();

        var host = new WebHostBuilder()
            .UseUrls("http://*:5000")
            .UseConfiguration(config)
            .UseKestrel()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseIISIntegration()
            .UseStartup<Startup>()
            .Build();

        host.Run();

generalsettings.json 包含以下数据:

{
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    }
  }
}

因此我注释掉了默认的Startup 类的构造函数。然后我注意到这是分配IConfigurationRoot Configuration 的位置,因此,当我尝试从ConfigureServices 使用它时,它是空的。我正在尝试使用(我认为)在ProgramMain 中构建的配置。我在这里错过了什么?

更新

为了清楚起见:我正在尝试在 Startup 类中使用 args

【问题讨论】:

  • 你到底想在这里完成什么。我觉得我认为您正在尝试做的事情可以使用您的 launchSettings.json 来完成。哪个应该在项目的属性中。
  • 我正在尝试在Startup 文件中使用args

标签: asp.net .net configuration asp.net-core kestrel-http-server


【解决方案1】:

事实证明,GitHub Aspnet hosting repo issues area 已经对这类事情进行了大量讨论。 GitHub 存储库始终是查看此类有趣问题的好地方。

给大家总结一下,不要在Program.Main中设置IConfigurationRoot,在Startup中设置。您可以将命令行参数从 Program.cs 传递给 Startup 构造函数,如下所示:

    public static void Main(string[] args)
    {
        var host = new WebHostBuilder()
            .UseKestrel()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseIISIntegration()
            .UseStartup<Startup>()
            .ConfigureServices(services => services
                .AddSingleton(new ConsoleArgs(args))
            )
            .Build();
        host.Run();
    }

其中 ConsoleArgs 是一个持有者类,您可以自己创建它,如下所示:

public class ConsoleArgs
{
    public ConsoleArgs(string[] args)
    {
        Args = args;
    }
    public string[] Args { get; }
}

显然,配置一个 ConsoleArgs 服务 是关键。这将允许它被注入到 Startup 构造函数中。然后你的 Startup 类构造函数看起来像

public Startup(IHostingEnvironment env, ConsoleArgs args)
{
     var builder = new ConfigurationBuilder()
    .SetBasePath(env.ContentRootPath)
    .AddJsonFile("generalsettings.json", optional: false, reloadOnChange: true)
    .AddEnvironmentVariables(prefix: "ASPNETCORE_")
    .AddCommandLine(args.Args);  
    var config = builder.Build();
}

这里的模式是“配置你的宿主环境程序,在启动时配置你的应用程序”

【讨论】:

  • 正确通过了args,但是在Configuration = builder.Build(); 上抛出了异常,说Unrecognized argument format: 'asdf'.(“asdf”是我通过测试的参数)。
  • 但是,当我将参数更改为 asdf=eee 时,它​​编译正常。那是因为参数应该是字典(键值)格式吗?
  • 是的,配置键的命名有一些假设。由于在添加环境变量或命令行项时 JSON 中定义的键/值会被覆盖,并且所有这些东西都必须在多个平台上运行,所以事物的名称有一些限制。 JSON 是树形结构,因为它表示和对象,但命令行参数和环境变量显然只是键简单值。所以定义一个重载 JSON 子对象值的 env var 有点神奇。有关详细信息,请参阅github.com/aspnet/Configuration。 :-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-30
  • 2015-06-30
  • 2016-07-11
  • 2012-12-17
  • 2013-09-21
  • 2012-02-15
相关资源
最近更新 更多