简体   繁体   English

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

[英]Automatically set appsettings.json for dev and release environments in asp.net core?

I've defined some values in my appsettings.json for things like database connection strings, webapi locations and the like which are different for development, staging and live environments.我在我的appsettings.json中定义了一些值,例如数据库连接字符串、webapi 位置等对于开发、暂存和实时环境是不同的。

Is there a way to have multiple appsettings.json files (like appsettings.live.json , etc, etc) and have the asp.net app just 'know' which one to use based on the build configuration it's running?有没有办法拥有多个appsettings.json文件(如appsettings.live.json等),并让 asp.net 应用程序根据其运行的构建配置“知道”使用哪个文件?

Update for .NET Core 3.0+ .NET Core 3.0+ 的更新

  1. You can use CreateDefaultBuilder which will automatically build and pass a configuration object to your startup class:您可以使用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 CreateDefaultBuilder自动包含适当的appsettings. Environment .json appsettings. Environment .json file so add a separate appsettings file for each environment: appsettings. Environment .json .json 文件,因此为每个环境添加一个单独的 appsettings 文件:

    appsettings.env.json

  3. Then set the ASPNETCORE_ENVIRONMENT environment variable when running / debugging然后在运行/调试时设置ASPNETCORE_ENVIRONMENT环境变量

How to set Environment Variables如何设置环境变量

Depending on your IDE, there are a couple places dotnet projects traditionally look for environment variables:根据您的 IDE,dotnet 项目通常会在几个地方查找环境变量:

  • For Visual Studio go to Project > Properties > Debug > Environment Variables:对于Visual Studio ,请转到项目 > 属性 > 调试 > 环境变量:

    Visual Studio - 环境变量

  • For Visual Studio Code , edit .vscode/launch.json > env :对于Visual Studio Code ,编辑.vscode/launch.json > env

    Visual Studio 代码 > 启动环境

  • Using Launch Settings , edit Properties/launchSettings.json > environmentVariables :使用Launch Settings ,编辑Properties/launchSettings.json > environmentVariables

    启动设置

    Which can also be selected from the Toolbar in Visual Studio也可以从 Visual Studio 的工具栏中选择

    启动设置下拉菜单

  • Using dotnet CLI , use the appropriate syntax for setting environment variables per your OS使用dotnet CLI ,使用适当的语法为每个操作系统设置环境变量

    Note : When an app is launched with dotnet run , launchSettings.json is read if available, and environmentVariables settings in launchSettings.json override environment variables.注意:当使用dotnet run启动应用程序时,将读取launchSettings.json (如果可用),并且 launchSettings.json 中的environmentVariables设置会覆盖环境变量。

How does Host.CreateDefaultBuilder work? Host.CreateDefaultBuilder如何工作?

.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: .NET Core 3.0 在平台扩展下添加了Host.CreateDefaultBuilder ,它将提供IConfiguration的默认初始化,它按以下顺序为应用程序提供默认配置:

  1. appsettings.json using the JSON configuration provider . appsettings.json使用JSON 配置提供程序
  2. appsettings. Environment .json appsettings. Environment .json using the JSON configuration provider .使用JSON 配置提供程序appsettings. Environment .json For example:例如:
    • appsettings. Production .json appsettings. Production .json or appsettings. Production .json
    • 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进一步阅读 - MS Docs

I have added screenshots of a working environment, because it cost me several hours of R&D.我添加了工作环境的截图,因为它花费了我几个小时的研发时间。

  1. First, add a key to your launch.json file.首先,在您的launch.json文件中添加一个密钥。

    See the below screenshot, I have added Development as my environment.请参阅下面的屏幕截图,我已将Development添加为我的环境。

    在 launch.json 中声明环境变量

  2. Then, in your project, create a new appsettings.{environment}.json file that includes the name of the environment.然后,在您的项目中,创建一个包含环境名称的新appsettings.{environment}.json文件。

    In the following screenshot, look for two different files with the names:在以下屏幕截图中,查找具有以下名称的两个不同文件:

    • appsettings.Development.Json
    • appSetting.json


    appsettings JSON 文件的项目视图

  3. And finally, configure it to your StartUp class like this:最后,将其配置到您的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"

    where "Development" is the name of my environment.其中"Development"是我的环境的名称。

In ASP.NET Core you should rather use Environment Variables instead of build configuration for proper appsettings.json在 ASP.NET Core 中,您应该使用环境变量而不是构建配置以获得正确的 appsettings.json

  1. Right click on you project > Properties > Debug > Environment Variables右键单击您的项目>属性>调试>环境变量

    环境变量

  2. ASP.NET Core will use the appropriate appsettings.json file: ASP.NET Core 将使用适当的 appsettings.json 文件:

    解决方案资源管理器中的 appsettings 文件示例

  3. Now you can use that Environment Variable like this:现在您可以像这样使用该环境变量:

     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.注意:如果您使用@Dmitry 的答案,您可能会遇到问题,例如。 when overriding appsettings.json values on Azure.在 Azure 上覆盖 appsettings.json 值时。

You can make use of environment variables and the ConfigurationBuilder class in your Startup constructor like this:您可以在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();
}

Then you create an appsettings.xxx.json file for every environment you need, with "xxx" being the environment name.然后为您需要的每个环境创建一个appsettings.xxx.json文件,其中“xxx”是环境名称。 Note that you can put all global configuration values in your "normal" appsettings.json file and only put the environment specific stuff into these new files.请注意,您可以将所有全局配置值放入“普通” appsettings.json文件中,并且仅将环境特定的内容放入这些新文件中。

Now you only need an environment variable called ASPNETCORE_ENVIRONMENT with some specific environment value ("live", "staging", "production", whatever).现在您只需要一个名为ASPNETCORE_ENVIRONMENT的环境变量,它具有一些特定的环境值(“live”、“staging”、“production”等)。 You can specify this variable in your project settings for your development environment, and of course you need to set it in your staging and production environments also.您可以在开发环境的项目设置中指定此变量,当然您还需要在暂存和生产环境中进行设置。 The way you do it there depends on what kind of environment this is.你在那里做的方式取决于这是什么样的环境。

UPDATE: I just realized you want to choose the appsettings.xxx.json based on your current build configuration .更新:我刚刚意识到您想根据您当前的构建配置选择appsettings.xxx.json This cannot be achieved with my proposed solution and I don't know if there is a way to do this.我提出的解决方案无法实现这一点,我不知道是否有办法做到这一点。 The "environment variable" way, however, works and might as well be a good alternative to your approach.但是,“环境变量”方式有效,并且可能是您的方法的一个很好的替代方案。

You may use conditional compilation:您可以使用条件编译:

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();
}

Just an update for .NET core 2.0 users, you can specify application configuration after the call to CreateDefaultBuilder :只是 .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);

   }
 }
  1. Create multiple appSettings. $(Configuration) .json创建多个appSettings. $(Configuration) .json appSettings. $(Configuration) .json files like: appSettings. $(Configuration) .json文件,例如:

    • appSettings.staging.json
    • appSettings.production.json
  2. Create a pre-build event on the project which copies the respective file to appSettings.json :在项目上创建一个预构建事件,将相应的文件复制到appSettings.json

     copy appSettings.$(Configuration).json appSettings.json
  3. Use only appSettings.json in your Config Builder:在 Config Builder 中仅使用appSettings.json

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

This is version that works for me when using a console app without a web page:这是在没有网页的情况下使用控制台应用程序时适用的版本:

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);

You can add the configuration name as the ASPNETCORE_ENVIRONMENT in the launchSettings.json as below您可以在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)"
      }
    }
  }

.vscode/launch.json file is only used by Visual Studio as well as /Properties/launchSettings.json file. .vscode/launch.json 文件仅由 Visual Studio 以及 /Properties/launchSettings.json 文件使用。 Don't use these files in production.不要在生产中使用这些文件。

The launchSettings.json file: launchSettings.json 文件:

  1. Is only used on the local development machine.仅在本地开发机器上使用。
  2. Is not deployed.未部署。
  3. contains profile settings.包含配置文件设置。

    • Environment values set in launchSettings.json override values set in the system environment在 launchSettings.json 中设置的环境值会覆盖在系统环境中设置的值

To use a file 'appSettings.QA.json' for example.例如,使用文件“appSettings.QA.json”。 You can use 'ASPNETCORE_ENVIRONMENT'.您可以使用“ASPNETCORE_ENVIRONMENT”。 Follow the steps below.请按照以下步骤操作。

  1. Add a new Environment Variable on the host machine and call it 'ASPNETCORE_ENVIRONMENT'.在主机上添加一个新的环境变量并将其命名为“ASPNETCORE_ENVIRONMENT”。 Set its value to 'QA'.将其值设置为“QA”。
  2. Create a file 'appSettings.QA.json' in your project.在您的项目中创建一个文件“appSettings.QA.json”。 Add your configuration here.在此处添加您的配置。
  3. Deploy to the machine in step 1. Confirm 'appSettings.QA.json' is deployed.在步骤 1 中部署到机器。确认已部署“appSettings.QA.json”。
  4. Load your website.加载您的网站。 Expect appSettings.QA.json to be used in here.期望在这里使用 appSettings.QA.json。

By adding the environment name in between the "appsettings" and ".json" part of the filename, it will override any settings that are in the main appsettings.json file.通过在文件名的"appsettings" ".json"之间添加环境名称,它将覆盖主appsettings.json文件中的所有设置。

For example, in the likehood that you have a different SQL Server connection string for a production environment, you can add that connection string to appsettings.Production.json , and it will use the value from that file.例如,如果生产环境有不同的 SQL 服务器连接字符串,您可以将该连接字符串添加到appsettings.Production.json ,它将使用该文件中的值。

在此处输入图像描述

I had the same issue that I wanted to change the appsettings.*.json file based on my chosen configuration in VS and I just discovered that you can just put "$(Configuration)" as value for "ASPNETCORE_ENVIRONMENT" in your launchSettings.json.我有同样的问题,我想根据我在 VS 中选择的配置更改 appsettings.*.json 文件,我刚刚发现你可以在你的 launchSettings.json 中将“$(Configuration)”作为“ASPNETCORE_ENVIRONMENT”的值.

This lets the default HostBuilder automatically pick the right appsettings.*.json-file.这让默认 HostBuilder 自动选择正确的 appsettings.*.json 文件。

I assume you still should do some other things so that your dev.appsettings won't be copied to production-server like described here for example Environment Based appsettings.json Configuration for publishing in .NET 5 .我假设你仍然应该做一些其他的事情,这样你的 dev.appsettings 就不会被复制到生产服务器,就像这里描述的那样,例如Environment Based appsettings.json Configuration for publishing in .NET 5 But it does the trick to test different environment during development and inside VS w/o deploying to another server or to manually set the ASPNETCORE_ENVIRONMENT-variable.但它确实可以在开发期间和在 VS 内部测试不同的环境而无需部署到另一台服务器或手动设置 ASPNETCORE_ENVIRONMENT 变量。

BTW: I tested with VS.顺便说一句:我用 VS 测试过。 I am not sure whether this also works with VS-Code.我不确定这是否也适用于 VS-Code。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM