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

Posted

技术标签:

【中文标题】为asp.net核心中的开发和发布环境自动设置appsettings.json?【英文标题】:Automatically set appsettings.json for dev and release environments in asp.net core? 【发布时间】:2018-03-04 00:11:42 【问题描述】:

我在appsettings.json 中为数据库连接字符串、webapi 位置等定义了一些值,这些值对于开发、暂存和实时环境是不同的。

有没有办法拥有多个appsettings.json 文件(如appsettings.live.json 等)并让asp.net 应用程序根据其运行的构建配置“知道”使用哪个文件?

【问题讨论】:

【参考方案1】:

当我使用没有网页的控制台应用程序时,这是适用于我的版本:

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

【讨论】:

【参考方案2】:

.vscode/launch.json 文件仅由 Visual Studio 以及 /Properties/launchSettings.json 文件使用。不要在生产中使用这些文件。

launchSettings.json 文件:

    仅在本地开发机器上使用。 未部署。

    包含配置文件设置。

    launchSettings.json 中设置的环境值覆盖系统环境中设置的值

以使用文件“appSettings.QA.json”为例。您可以使用“ASPNETCORE_ENVIRONMENT”。请按照以下步骤操作。

    在主机上添加一个新的环境变量并将其命名为“ASPNETCORE_ENVIRONMENT”。将其值设置为“QA”。 在您的项目中创建一个文件“appSettings.QA.json”。在此处添加您的配置。 在步骤 1 中部署到机器。确认已部署“appSettings.QA.json”。 加载您的网站。预计 appSettings.QA.json 将在此处使用。

【讨论】:

这是否意味着,如果您有 5 个环境和 5 个 appsettings.EnvName.json 文件,所有这些都将被部署并且只有一台选定的机器,因为构建定义的工件将包含所有 5 个文件?或者只应该部署 appsettings.json(作为主要)+ appsettings.CurrentEnvironment.json(作为覆盖)以及如何部署?【参考方案3】:

.NET Core 3.0+ 更新

    您可以使用CreateDefaultBuilder,它会自动构建配置对象并将其传递给您的启动类:

    WebHost.CreateDefaultBuilder(args).UseStartup<Startup>();
    
    public class Startup
    
        public Startup(IConfiguration configuration) // automatically injected
        
            Configuration = configuration;
        
        public IConfiguration Configuration  get; 
        /* ... */
    
    

    CreateDefaultBuilder 自动包含适当的 appsettings.<i>Environment</i>.json 文件,因此为每个环境添加单独的 appsettings 文件:

    然后在运行/调试时设置ASPNETCORE_ENVIRONMENT环境变量

如何设置环境变量

根据您的 IDE,dotnet 项目通常会在几个地方查找环境变量:

对于 Visual Studio,请转到项目 > 属性 > 调试 > 环境变量:

对于 Visual Studio 代码,编辑 .vscode/launch.json > env

使用启动设置,编辑Properties/launchSettings.json > environmentVariables

也可以从 Visual Studio 的工具栏中选择

使用 dotnet CLI,为 setting environment variables per your OS 使用适当的语法

注意:当使用dotnet run 启动应用程序时,会读取launchSettings.json(如果可用),并且launchSettings.json 中的environmentVariables 设置会覆盖环境变量。

Host.CreateDefaultBuilder 是如何工作的?

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

    appsettings.json 使用 JSON configuration provider。 appsettings.<i>Environment</i>.json 使用 JSON configuration provider。例如: appsettings.<i>Production</i>.jsonappsettings.<i>Development</i>.json App secrets 当应用在开发环境中运行时。 环境变量使用Environment Variables configuration provider。 命令行参数使用Command-line configuration provider。

进一步阅读 - MS Docs

App startup in ASP.NET Core Configuration in ASP.NET Core Use multiple environments in ASP.NET Core

【讨论】:

谢谢,很好,但是如何使用控制台进程(或工作进程模板/脚手架)来做到这一点? 这不适用于最新版本,它将始终采用 appsettings.json 并忽略 appsettings.development.json。 Run (dev) 和 run (prod) 也不见了。 这应该是公认的答案。【参考方案4】:

在 ASP.NET Core 中,您应该使用环境变量而不是构建配置以获得正确的 appsettings.json

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

    ASP.NET Core 将使用适当的 appsettings.json 文件:

    现在您可以像这样使用该环境变量:

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

注意:如果您使用@Dmitry's answer,您可能会遇到问题,例如。 在 Azure 上覆盖 appsettings.json 值时。

【讨论】:

【参考方案5】:

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

    首先,在您的launch.json 文件中添加一个密钥。

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

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

    在以下屏幕截图中,查找两个具有不同名称的文件:

    appsettings.Development.Json appSetting.json

    最后,将它配置到您的 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();
    
    

    最后,你可以像这样从命令行运行它:

    dotnet run --environment "Development"
    

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

【讨论】:

试过了,效果很好。 VS2017 甚至在基础文件下显示不同的版本。赞成票。 当 ihostingenvironment 被弃用时,你如何在 core 2.2 中做到这一点 @djack109 你应该改用IWebHostEnvironment【参考方案6】:

    创建多个appSettings.<i>$(Configuration)</i>.json 文件,例如:

    appSettings.staging.json appSettings.production.json

    在项目上创建一个预构建事件,将相应的文件复制到appSettings.json

    copy appSettings.$(Configuration).json appSettings.json
    

    在您的配置生成器中仅使用 appSettings.json

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

【讨论】:

这应该是一个可以接受的答案。复杂情况可以使用SlowCheetah。 如何在项目上创建预构建事件?该行的起始副本应该放在哪里......实际上应该放在哪里? @Paul 在 Visual Studio 中,右键单击解决方案资源管理器视图中的项目,从右键菜单中选择 Properties,然后在属性视图中选择 Build Events【参考方案7】:

您可以在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)"
      
    
  

【讨论】:

【参考方案8】:

你可以使用条件编译:

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

【讨论】:

您应该在 MSBuild/TFS 构建中设置环境变量。条件编译会导致 CI​​ 构建中容易处理的错误。即 .AddJsonFile($"appsettings.env.EnvironmentName.json", optional: true) 环境变量见我的回答 (***.com/a/50331886/1319086) 这种方法强制为每个环境专门重新编译代码,使其无法重新分发/安装到其他地方。 问题是关于“了解构建配置” 这不应被标记为已接受的答案 - 尽管这是一个解决方案,但它不是最佳实践。【参考方案9】:

只是针对.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);

   
 

【讨论】:

如何在使用的环境之间切换?是否应该在任何配置文件中进行更改?我知道我需要将项目在 Azure 上运行时要使用的 URL 添加到 appsettings.json 并将本地运行时要执行的 URL(按 F5)添加到 appsettings.Development.json。那是对的吗?我要使用的字符串在文件 launchSettings.json 中,我有点不清楚如何根据应用程序的执行位置(或者是否应该在全部)。 @DonkeyBanana 环境只不过是项目属性中指定的设置。在 VS 2017 中,右键单击项目 > 属性。在调试下,您将看到密钥 ASPNETCORE_ENVIRONMENT 的当前环境。该值将替换为ctx.HostingEnvironment.EnvironmentName。因此,如果您在属性中将该值设置为“生产”,项目将在根文件夹中查找config.Production.json 文件。欲了解更多信息,请查看此link 在 WebHost.CreateDefaultBuiler(... 中创建一个Error CS0266 Cannot implicitly convert type 'Microsoft.AspNetCore.Hosting.IWebHost' to 'Microsoft.AspNetCore.Hosting.IWebHostBuilder'. An explicit conversion exists (are you missing a cast?) 值得注意的是,here 指出“当您使用 CreateDefaultBuilder 初始化新的主机构建器时,会自动调用两次 AddJsonFile”。换句话说,它已经在加载 appSettings.json,然后根据您的环境配置,它正在加载 appsettings.Environment.json @umutsen 在最新的 Visual Studio 中没有更多的运行环境设置【参考方案10】:

您可以像这样在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”、“staging”、“production”等)。您可以在开发环境的项目设置中指定此变量,当然您还需要在暂存和生产环境中进行设置。你在那里做的方式取决于这是什么样的环境。

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

【讨论】:

我在项目属性->调试部分中查看了使用环境变量,但是没有明显的方法将如何根据项目设置进行更改。那是我可以添加到我的项目中来处理它的另一个文件吗? 在项目属性中设置变量仅适用于在您的开发环境(可能是 Visual Studio)中使用它。您需要根据特定环境(IIS、Azure)为您部署的应用程序在其他地方设置它。我不建议在某个配置文件中设置该变量,因为该文件也可能被部署,然后覆盖服务器值。 您在构建配置中设置它。如果没有构建配置文件,那么他们是手动进行的,因此他们需要在(过时的)部署配置文件中进行设置 我在 Azure 中有多个环境,例如测试、登台和生产。如果我想将 Web 应用的发布版本从 VS 发布到 Azure,我应该在哪里更改 ASPNETCORE_ENVIRONMENT 变量? 我们在部署过程中不会更改变量,而是内置在特定环境中。在 Azure 中,您可以直接在“应用程序设置”下的应用服务配置中设置这些值。如果您使用多个插槽,请不要忘记将它们标记为“部署插槽设置”。

以上是关于为asp.net核心中的开发和发布环境自动设置appsettings.json?的主要内容,如果未能解决你的问题,请参考以下文章

为测试人员存档时,如何将 .entitlements 中的“APS 环境”值设置为“开发”?

asp.net 核心环境变量未传递给 vuejs 配置

处理asp.net核心中的异常?

如何在Asp.net Core的登录过程中为“记住我”设置单个cookie超时?

uri查询参数中的asp.net核心JWT?

IIS 中的 Asp.Net 核心 MVC 应用程序 Windows 身份验证