为 asp.net 核心中的开发和发布环境自动设置 appsetings.json?

我已经在 appsettings.json中为数据库连接字符串、 webapi 位置等定义了一些值,这些值对于开发、准备和活动环境而言是不同的。

有没有一种方法可以拥有多个 appsettings.json文件(比如 appsettings.live.json等等) ,并让 asp.net 应用根据它正在运行的构建配置“知道”使用哪一个?

266498 次浏览

您可以像下面这样使用环境变量和 Startup构造函数中的 ConfigurationBuilder类:

public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
this.configuration = builder.Build();
}

然后为您需要的每个环境创建一个 appsettings.xxx.json文件,其中“ xxx”是环境名称。注意,您可以将所有全局配置值放入“普通”appsettings.json文件中,并且只将特定于环境的内容放入这些新文件中。

现在,您只需要一个名为 ASPNETCORE_ENVIRONMENT的环境变量,它具有一些特定的环境值(“ live”、“ stage”、“ production”等等)。您可以在您的开发环境的项目设置中指定此变量,当然您也需要在您的准备和生产环境中设置它。你在那里做的方式取决于这是什么样的环境。

更新: 我刚刚意识到你想根据你现在的 构建配置选择 appsettings.xxx.json。这是无法实现的,我提出的解决方案,我不知道是否有办法做到这一点。然而,“环境变量”方法是有效的,也可能是你方法的一个很好的替代方法。

我已经添加了一个工作环境的截图,因为它花费了我几个小时的研发。

  1. 首先,向 launch.json文件添加一个密钥。

    看下面的截图,我已经添加了 Development作为我的环境。

    Declaration of the environment variable in launch.json

  2. 然后,在项目中创建一个包含环境名称的新 appsettings.{environment}.json文件。

    在下面的截图中,查找两个不同的文件名:

    • appsettings.Development.Json
    • appSetting.json


    Project view of appsettings JSON files

  3. 最后,将其配置为 StartUp类,如下所示:

    public Startup(IHostingEnvironment env)
    {
    var builder = new ConfigurationBuilder()
    .SetBasePath(env.ContentRootPath)
    .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
    .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
    .AddEnvironmentVariables();
    
    
    Configuration = builder.Build();
    }
    
  4. And at last, you can run it from the command line like this:

    dotnet run --environment "Development"
    

    其中 "Development"是我的环境的名称。

你可使用条件式编译:

public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
#if SOME_BUILD_FLAG_A
.AddJsonFile($"appsettings.flag_a.json", optional: true)
#else
.AddJsonFile($"appsettings.no_flag_a.json", optional: true)
#endif
.AddEnvironmentVariables();
this.configuration = builder.Build();
}

只是对.NET core 2.0用户的一个更新,您可以在调用 CreateDefaultBuilder之后指定应用程序配置:

public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}


public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration(ConfigConfiguration)
.UseStartup<Startup>()
.Build();


static void ConfigConfiguration(WebHostBuilderContext ctx, IConfigurationBuilder config)
{
config.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("config.json", optional: false, reloadOnChange: true)
.AddJsonFile($"config.{ctx.HostingEnvironment.EnvironmentName}.json", optional: true, reloadOnChange: true);


}
}

在 ASP.NET Core 中,您应该使用 Environment Variables,而不是为适当的 appsetings.json 构建配置

  1. 右键单击您的项目 > 属性 > 调试 > 环境变量

    environment variables

  2. NET Core 将使用适当的 appsetings.json 文件:

    example of appsettings files in solution explorer

  3. 现在你可以像这样使用这个环境变量:

    public Startup(IHostingEnvironment env)
    {
    var builder = new ConfigurationBuilder()
    .SetBasePath(env.ContentRootPath)
    .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
    .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
    .AddEnvironmentVariables();
    
    
    Configuration = builder.Build();
    }
    

Note: If you use @Dmitry's answer, you can run into problems eg. when overriding appsettings.json values on Azure.

您可以在 launchSettings.json中将配置名称添加为 ASPNETCORE_ENVIRONMENT,如下所示

  "iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:58446/",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"environmentVariables": {
ASPNETCORE_ENVIRONMENT": "$(Configuration)"
}
}
}
  1. 创建多个 appSettings.$(Configuration).json文件,如:

    • appSettings.staging.json
    • appSettings.production.json
  2. 在项目上创建一个预生成事件,将相应的文件复制到 appSettings.json:

    copy appSettings.$(Configuration).json appSettings.json
    
  3. Use only appSettings.json in your Config Builder:

    var builder = new ConfigurationBuilder()
    .SetBasePath(env.ContentRootPath)
    .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
    .AddEnvironmentVariables();
    
    
    Configuration = builder.Build();
    

更新.NET Core 3.0 +

  1. 你可以使用 CreateDefaultBuilder,它会自动构建一个配置对象并传递给你的启动类:

    WebHost.CreateDefaultBuilder(args).UseStartup<Startup>();
    
    public class Startup
    {
    public Startup(IConfiguration configuration) // automatically injected
    {
    Configuration = configuration;
    }
    public IConfiguration Configuration { get; }
    /* ... */
    }
    
  2. CreateDefaultBuilder automatically includes the appropriate appsettings.Environment.json file so add a separate appsettings file for each environment:

    appsettings.env.json

  3. Then set the ASPNETCORE_ENVIRONMENT environment variable when running / debugging

How to set Environment Variables

Depending on your IDE, there are a couple places dotnet projects traditionally look for environment variables:

  • For Visual Studio go to Project > Properties > Debug > Environment Variables:

    Visual Studio - Environment Variables

  • For Visual Studio Code, edit .vscode/launch.json > env:

    Visual Studio Code > Launch Environment

  • Using Launch Settings, edit Properties/launchSettings.json > environmentVariables:

    Launch Settings

    Which can also be selected from the Toolbar in Visual Studio

    Launch Settings Dropdown

  • Using dotnet CLI, use the appropriate syntax for setting environment variables per your OS

    Note: When an app is launched with dotnet run, launchSettings.json is read if available, and environmentVariables settings in launchSettings.json override environment variables.

How does Host.CreateDefaultBuilder work?

.NET Core 3.0 added Host.CreateDefaultBuilder under platform extensions which will provide a default initialization of IConfiguration which provides default configuration for the app in the following order:

  1. appsettings.json using the JSON configuration provider.
  2. appsettings.Environment.json using the JSON configuration provider. For example:
    • appsettings.Production.json or
    • appsettings.Development.json
  3. App secrets when the app runs in the Development environment.
  4. Environment variables using the Environment Variables configuration provider.
  5. Command-line arguments using the Command-line configuration provider.

Further Reading - MS Docs

. vscode/launch.json 文件只由 Visual Studio 和/Properties/launchSettings.json 文件使用。

Json 文件:

  1. 仅在本地开发计算机上使用。
  2. 未部署。
  3. 包含配置文件设置。

    • Json 中设置的环境值覆盖系统环境中设置的值

例如,可以使用文件‘ appSettings.QA.json’,可以使用‘ ASPNETCORE _ ENVIRONMENT’。

  1. 在主机上添加一个新的环境变量,命名为“ ASPNETCORE _ ENVIRONMENT”,将其值设置为“ QA”。
  2. 在项目中创建一个文件‘ appSettings.QA.json’。
  3. 在步骤1中部署到机器。确认已部署“ appSettings.QA.json”。
  4. 加载你的网站。期待 appSettings.QA.json 在这里使用。

这个版本适合我在没有网页的情况下使用控制台应用程序:

var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json", optional: true);


IConfigurationRoot configuration = builder.Build();
AppSettings appSettings = new AppSettings();
configuration.GetSection("AppSettings").Bind(appSettings);

我有同样的问题,我想更改应用程序设置。*.基于我在 VS 中选择的配置,我刚刚发现可以在 launchSettings.json 中将“ $(Configuration)”作为“ ASPNETCORE _ ENVIRONMENT”的值。

这让默认 HostBuilder 自动选择正确的 appsets.* . json-file。

我假设您仍然应该做一些其他的事情,这样就不会像这里描述的例如 用于在.NET 5中发布的基于环境的 appsetings.json 配置那样将 dev.appset 复制到生产服务器。但是它可以在开发期间测试不同的环境,并在 VS w/o 中部署到另一个服务器,或者手动设置 ASPNETCORE _ ENVIRONMENT 变量。

顺便说一下: 我测试了 VS,我不确定这是否也适用于 VS 代码。

通过在文件名的 "appsettings"".json"部分之间添加环境名称,它将覆盖主 appsettings.json文件中的所有设置。

例如,在生产环境中可能有不同的 SQLServer 连接字符串,您可以将该连接字符串添加到 appsettings.Production.json,它将使用该文件中的值。

enter image description here