读取 Main Program.cs 中的 appsettings.json

Posted

技术标签:

【中文标题】读取 Main Program.cs 中的 appsettings.json【英文标题】:Read appsettings.json in Main Program.cs 【发布时间】: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; 

【问题讨论】:

【参考方案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()

以上是关于读取 Main Program.cs 中的 appsettings.json的主要内容,如果未能解决你的问题,请参考以下文章

blazor wasm 在 program.cs Main 中注入 IJSRuntime

将依赖项传递给 .NET 6 中 program.cs 中的 app.[Methods()]

是否有充分的理由在 Program.cs/main 中编写代码而不是使用类? [关闭]

我的项目里边真的没有program.cs文件

ASP.NET Core 中的 Main 方法

Main() 方法的参数