【问题标题】:Read appsettings.json in Main Program.cs读取 Main Program.cs 中的 appsettings.json
【发布时间】:2017-06-03 23:15:37
【问题描述】:

首先,我的主要目的是为我的应用程序动态设置 IP 和端口。

我正在使用IConfiguration 注入一个 json 配置文件,就像提到的一些教程一样。

但是,我无法检索 Program.cs 中的配置,因为我的 WebHostBuilder 将同时使用 StartUp 和 Url。

所以在主机建立时,我的配置中没有任何内容。

WebProtocolSettings settings_Web = new WebProtocolSettings();
var host = new WebHostBuilder()
                .UseIISIntegration()
                .UseKestrel()
                .UseContentRoot(Directory.GetCurrentDirectory())
                .UseStartup<Startup>()
                .UseUrls(settings_Web.Url + ":" + settings_Web.Port)
                .Build();

在 Startup.cs 中

public Startup(IHostingEnvironment env)
{
    // Set up configuration sources.
    var builder = new ConfigurationBuilder()
        .SetBasePath(env.ContentRootPath)
        .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);

    Configuration = builder.Build();
}

public IConfigurationRoot Configuration { get; set; }

public void ConfigureServices(IServiceCollection services)
{
    // Adds services required for using options.
    services.AddOptions();

    var _WebProtocolSettings = Configuration.GetSection("WebProtocolSettings");

    // Register the IConfiguration instance
    services.Configure<WebProtocolSettings>(_WebProtocolSettings);
}

我的 appsettings.json:

{
    "WebProtocolSettings": {
        "Url": "127.0.0.1",
        "Port": 5050
    }
}

我的 WebProtocolSettings.cs:

public class WebProtocolSettings
{
    public string Url { get; set; }
    public int Port { get; set; }
}

【问题讨论】:

    标签: c# asp.net-core asp.net-core-1.0


    【解决方案1】:

    您必须在 main 方法中构建配置,获取该部分并将其绑定到您的模型。没办法。

    public static void Main(string[] args)
    {
        var config = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json", optional: false)
            .Build();
    
        WebProtocolSettings settings_Web = new WebProtocolSettings();
        config.GetSection("WebProtocolSettings").Bind(settings_Web);
    
        var host = new WebHostBuilder()
                .UseIISIntegration()
                .UseKestrel()
                .UseContentRoot(Directory.GetCurrentDirectory())
                .UseStartup<Startup>()
                .UseUrls(settings_Web.Url + ":" + settings_Web.Port)
                .Build()
    
        host.Run();
    }
    

    更新

    另一种方法是将配置传递给UseConfiguration,如

    中所述
    public static void Main(string[] args)
    {
        var config = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("hosting.json", optional: true)
            .AddCommandLine(args)
            .Build();
    
        var host = new WebHostBuilder()
            .UseUrls("http://*:5000")
            .UseConfiguration(config)
            .UseKestrel()
            .Configure(app =>
            {
                app.Run(context => 
                    context.Response.WriteAsync("Hello, World!"));
            })
            .Build();
    
        host.Run();
    }
    

    或在 ASP.NET Core > 2.0

    public static void Main(string[] args)
    {
        BuildWebHost(args).Run();
    }
    
    public static IWebHost BuildWebHost(string[] args)
    {
        var config = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("hosting.json", optional: true)
            .AddCommandLine(args)
            .Build();
    
        return WebHost.CreateDefaultBuilder(args)
            .UseUrls("http://*:5000")
            .UseConfiguration(config)
            .Configure(app =>
            {
                app.Run(context => 
                    context.Response.WriteAsync("Hello, World!"));
            })
            .Build();
    }
    

    【讨论】:

    • 嗨@Tseng,谢谢你的回答,但是,我如何在Main Program.cs中归档“appsettings.json”的路径?
    • 它必须与应用程序位于同一文件夹中。在启动类中调用它时适用相同的规则
    • 我找到了方法:.SetBasePath(Directory.GetCurrentDirectory())。另外,应该是config.GetSection 而不是Configuration.GetSection。感谢您的帮助
    • @Tseng 如果你需要访问hostingContext.HostingEnvironment.EnvironmentName,因为你有环境特定的hosting.json文件?
    • @DanCundy:(Azure) 应用服务值是通过环境变量设置的,因此您必须添加 .AddEnvironmentVariables()AddXxx 的顺序是被覆盖的顺序(最新的密钥获胜,所以最后注册的将覆盖前一个 - 如果它定义了特定的密钥)。但是现在你有Generic Host 可以轻松引导控制台运行服务
    【解决方案2】:

    .UseConfiguration(Tseng 的替代答案)是最简单的方法,但请注意,以这种方式配置时,在运行时对配置文件所做的更改不会应用于您的 IConfiguration 对象。要保持配置动态,您必须使用.ConfigureAppConfiguration - 但是您必须在Main() 中使用额外的时间来构建配置。但是,您可以重复使用配置它的代码。

    ASP.NET Core 2.2:

        public static void Main(string[] args)
        {
            IConfigurationBuilder configBuilderForMain = new ConfigurationBuilder();
            ConfigureConfiguration(configBuilderForMain);
            IConfiguration configForMain = configBuilderForMain.Build();
    
            // ... use configForMain to read config here ...
    
            var host = new WebHostBuilder()
                .ConfigureAppConfiguration(ConfigureConfiguration)
                // ... the rest of it ...
                .Build();
        }
    
        public static void ConfigureConfiguration(IConfigurationBuilder config)
        {
            config.SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
        }
    

    【讨论】:

      【解决方案3】:

      在 asp.net core 3.1 中,您可以通过hostContext 访问配置。此示例基于 Worker 服务项目:

      public class Program
          {
              public static void Main(string[] args)
              {
                  CreateHostBuilder(args).Build().Run();
              }
      
              public static IHostBuilder CreateHostBuilder(string[] args) =>
                  Host.CreateDefaultBuilder(args)
                      .ConfigureServices((hostContext, services) =>
                      {
                          //Access configuration here with the Host Context.  For example, to get a connection string from AppSettings.json:
                          var connectionString = hostContext.Configuration.GetConnectionString("MyConnectionString");
                          services.AddHostedService<Worker>();
                      });
          }
      

      【讨论】:

      • ConfigureServises 在调用 ConfigureWebHostDefaults 之后被调用。所以在这种情况下这将无济于事。
      • 正是我想要的。
      【解决方案4】:

      支持命令行参数和默认appsettings文件的扩展方法:

      public static class ConfigurationExtensions
      {
          public static IConfigurationRoot BuildConfigurationRoot()
          {
      
              var args = Environment.GetCommandLineArgs();
              var envArg = args.IndexOf("--environment");
              var envFromArgs = envArg >= 0 ? args[envArg + 1] : null;
      
              var aspnetcore = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
              var dotnetcore = Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT");
      
              var environment = envFromArgs ?? (string.IsNullOrWhiteSpace(aspnetcore)
                  ? dotnetcore
                  : aspnetcore);
      
              var configuration = new ConfigurationBuilder()
                  .AddCommandLine(Environment.GetCommandLineArgs())
                  .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                  .AddJsonFile(
                      $"appsettings.{environment}.json",
                      optional: true)
                  .Build();
      
              return configuration; 
          }
      }
      

      【讨论】:

      • 您是否想在 .Build() 之前添加“.AddEnvironmentVariables()”作为一行?
      【解决方案5】:

      在 .NET 6 中

      var builder = WebApplication.CreateBuilder(args);
      
      var configValue = builder.Configuration.GetValue<string>("Authentication:CookieAuthentication:LoginPath");
      

      【讨论】:

        【解决方案6】:

        在 .net core 3.1 中,您可以使用 ConfigurationHelper.GetConfiguration() 来获取 appSetting 变量:

        appSettings.json

        "Endpoint": {
        "ip": "170.888.88.888",
        "port": 88888}
        

        程序.cs

        public class Program
        {
            public static void Main(string[] args)
            {
             var config = ConfigurationHelper.GetConfiguration();
             var ip = config["Endpoint:ip"];
             var port = config["Endpoint:port"];
            }
         }
        

        【讨论】:

        • “ConfigurationHelper”从何而来?我看到了一些具有此名称的自定义类的示例,但在幕后,它们的作用与接受的答案相同。
        【解决方案7】:

        使用此代码:

        public class Program
        {
            private static string _environmentName;
        
            public static void Main(string[] args)
            {
                var webHost = BuildWebHost(args);
        
                var config = new ConfigurationBuilder()
                    .SetBasePath(Directory.GetCurrentDirectory())
                    .AddJsonFile($"appsettings.{_environmentName}.json", optional: true, reloadOnChange: true)
                    .AddCommandLine(args)
                    .Build();
        
                BuildWebHost(args).Run();
            }
        
            public static IWebHost BuildWebHost(string[] args) =>
                WebHost.CreateDefaultBuilder(args)
                    .ConfigureLogging((hostingContext, config) =>
            {
                config.ClearProviders();
                _environmentName = hostingContext.HostingEnvironment.EnvironmentName;
            }).UseStartup<Startup>().Build();
        }
        

        【讨论】:

        • 我忘了把 BuildWebHost(args).Run();在完成方法 Main()
        猜你喜欢
        • 2019-11-19
        • 1970-01-01
        • 1970-01-01
        • 2021-04-19
        • 2021-11-22
        • 2019-02-28
        • 1970-01-01
        • 1970-01-01
        • 2018-08-05
        相关资源
        最近更新 更多