ChatGPT解决这个技术问题 Extra ChatGPT

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

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

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


K
KyleMit

.NET Core 3.0+ 的更新

您可以使用 CreateDefaultBuilder,它将自动构建配置对象并将其传递给您的启动类: WebHost.CreateDefaultBuilder(args).UseStartup(); public class Startup { public Startup(IConfiguration configuration) // 自动注入 { Configuration = configuration; } 公共 IConfiguration 配置 { 获取; } /* ... */ } CreateDefaultBuilder 自动包含相应的 appsettings.Environment.json 文件,因此为每个环境添加一个单独的 appsettings 文件:然后在运行/调试时设置 ASPNETCORE_ENVIRONMENT 环境变量

如何设置环境变量

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

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

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

使用启动设置,编辑 Properties/launchSettings.json > environmentVariables: 也可以从 Visual Studio 的工具栏中选择

使用 dotnet CLI,使用适当的语法为每个操作系统设置环境变量 注意:当使用 dotnet run 启动应用程序时,将读取 launchSettings.json(如果可用),并且 launchSettings.json 中的 environmentVariables 设置会覆盖环境变量。

Host.CreateDefaultBuilder 如何工作?

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

appsettings.json 使用 JSON 配置提供程序。 appsettings.Environment.json 使用 JSON 配置提供程序。例如:appsettings.Production.json 或 appsettings.Development.json 应用程序在开发环境中运行时的应用程序机密。使用环境变量配置提供程序的环境变量。使用命令行配置提供程序的命令行参数。

进一步阅读 - MS Docs

ASP.NET Core 中的应用启动

ASP.NET Core 中的配置

在 ASP.NET Core 中使用多个环境


谢谢,很好,但是如何使用控制台进程(或工作进程模板/脚手架)来做到这一点?
这不适用于最新版本,它将始终采用 appsettings.json 并忽略 appsettings.development.json。运行(开发)和运行(产品)也不见了。
这应该是公认的答案。
这也适用于自定义环境名称吗?例如,如果我想将 ASPNETCORE_ENVIRONMENT 设置为“Dev”。会自动获取名为 appsettings.Dev.json 的 appsettings 吗?
@Mehnaz,我相信是的。我认为您不受任何预设可用环境名称的约束。它只会采用您在环境变量中设置的任何名称,并使用它来构建应用程序设置文件的命名规则。
K
KyleMit

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

首先,在您的 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();配置 = builder.Build();最后,您可以像这样从命令行运行它: dotnet run --environment "Development" 其中“Development”是我的环境的名称。


试过这个,效果很好。 VS2017 甚至在基础文件下显示不同的版本。赞成票。
当 ihostingenvironment 被弃用时,你如何在核心 2.2 中做到这一点
@djack109 你应该使用 IWebHostEnvironment 代替。
K
KyleMit

在 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();配置 = builder.Build(); }

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


O
Onkel Toob

您可以像这样在 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 中,您可以直接在“应用程序设置”下的应用服务配置中设置这些值。如果您使用多个插槽,请不要忘记将它们标记为“部署插槽设置”。
D
Dmitry

您可以使用条件编译:

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)
有关环境变量,请参阅我的答案 (stackoverflow.com/a/50331886/1319086)
这种方法会强制为每个环境专门重新编译代码,从而无法在其他地方重新分发/安装。
问题是关于“了解构建配置”
这不应被标记为已接受的答案 - 尽管这是一个解决方案,但它不是最佳实践。
u
umutesen

只是针对 .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,将本地运行时(按 F5)我要执行的 URL 添加到 appsettings.Development.json。那是对的吗?我要使用的字符串在文件launchSettings.json 中,我有点不清楚如何根据应用程序的执行位置(或者是否应该更改它)来更改它。
@DonkeyBanana 环境只不过是项目属性中指定的设置。在VS 2017中,右键项目>特性。在调试下,您将看到密钥 ASPNETCORE_ENVIRONMENT 的当前环境。该值将替换为 ctx.HostingEnvironment.EnvironmentName}。因此,如果您在属性中将该值设置为“生产”,则项目将在根文件夹中查找 config.Production.json 文件。有关详细信息,请查看此link
在 WebHost.CreateDefaultBuiler(...
值得注意的是,here 它指出“当您使用 CreateDefaultBuilder 初始化新的主机构建器时,会自动调用两次 AddJsonFile”。换句话说,它已经在加载 appSettings.json,然后根据您的环境配置,它正在加载 appsettings.{Environment}.json
@umutsen 在最新的视觉工作室中,没有更多的运行环境设置
K
KyleMit

创建多个 appSettings.$(Configuration).json 文件,例如:appSettings.staging.json appSettings.production.json 在项目上创建一个预构建事件,将相应的文件复制到 appSettings.json:复制 appSettings.$(Configuration)。 json appSettings.json 在配置生成器中仅使用 appSettings.json: var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .AddEnvironmentVariables();配置 = builder.Build();


这应该是一个公认的答案。对于复杂的情况,可以使用 SlowCheetah
您如何在项目上创建预构建事件?那行起始副本应该放在哪里......实际上应该放在哪里?
@Paul 在 Visual Studio 中,右键单击解决方案资源管理器视图中的项目,从右键菜单中选择 Properties,然后在属性视图中选择 Build Events
这是完美的 - 允许我构建应用程序并将我们的 QA/Test 和 UAT 部署到一台机器上,而无需复制应用程序设置并使用上述在机器级别设置它的方法。正是需要的东西——我认为这个人在上面寻找什么。
N
Nick Cordova

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

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

L
LuFFy

您可以将配置名称添加为 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)"
      }
    }
  }

O
Oks Xen

.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(作为替代)以及如何部署?
T
TheZero0ne

我有同样的问题,我想根据我在 VS 中选择的配置更改 appsettings.*.json 文件,我刚刚发现你可以在你的 launchSettings.json 中将“$(Configuration)”作为“ASPNETCORE_ENVIRONMENT”的值.

这让默认 HostBuilder 自动选择正确的 appsettings.*.json 文件。

我假设您仍然应该做一些其他的事情,这样您的 dev.appsettings 就不会像这里所描述的那样被复制到生产服务器,例如 Environment Based appsettings.json Configuration for publishing in .NET 5。但它确实可以在开发期间和在 VS 内部测试不同的环境而无需部署到另一台服务器或手动设置 ASPNETCORE_ENVIRONMENT 变量。

顺便说一句:我用 VS 测试过。我不确定这是否也适用于 VS-Code。