如何使用 .NET Core 基于发布配置文件更新 appsettings.json?

How to update appsettings.json based on publish profile using .NET Core?

我目前正在从 .NET Framework 切换到 .NET Core。过去,我所有的应用程序设置都在 Web.config 文件中。当我添加一个新的发布配置文件时,我可以右键单击 select 'Add Config Transform' 这将在 Web.config 下生成一个嵌套的 Web.{Profile}.config 文件,我可以在其中设置应用程序设置具体到各自的配置文件。

现在,在 .NET Core 中,我想使用 appsettings.json 文件而不是 Web.config 文件来实现相同的效果。如何创建一个 appsettings.{Profile}.json 文件,该文件将嵌套在我的 appsettings.json 文件下并包含特定于我的发布配置文件的设置?当然,我可以手动创建文件,但是 'links' 设置为何会在应用程序发布时覆盖 appsettings.json?在 Visual Studio 中是否有一种简单的方法可以像我为我的旧 .NET Framework 项目所描述的那样做到这一点?还是我遗漏了什么?

谢谢!

but what is it that 'links' the settings so that they will override appsettings.json when the application is published?

应用程序设置由 WebHostProgram.cs

中配置
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>();

webhost.cs 的实现中,框架将应用程序设置添加到网络主机:

config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
      .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);

第二行是添加特定环境的地方appsettings。在 Visual Studio 中,此环境变量在 Project Settings -> Debug 页面中定义并称为 ASPNETCORE_ENVIRONMENT。默认情况下,它设置为 Development,因此当您在 Visual Studio 中构建和 运行 时,将加载 appsettings.development.json 文件(如果存在)并覆盖 appsettings.json 文件.

发布应用程序时,您可以使用同名的 OS 环境变量覆盖此值。有一个层次结构,其中 .NET Core 从中读取值并具有 "last one wins " 策略。

层次结构当前为:

  1. Files (appsettings.json, appsettings.{Environment}.json, where {Environment} is the app's current hosting environment)
  2. Azure Key Vault
  3. User secrets (Secret Manager) (in the Development environment only)
  4. Environment variables
  5. Command-line arguments

因此,当您发布应用程序时,您可以使用环境变量覆盖主机 OS 上的环境。当 .NET Core 启动您发布的应用程序时,它将读取该变量并加载适当的 appsettings.{environment}.json 文件。如果未设置该值,或者该环境不存在文件,则将应用 appsettings.json 中的设置。

您可以阅读有关 ASPNETCORE_ENVIROMENT 设置的更多信息 here

...自从我最初的评论以来,我发现 web.config 转换完全受 VS 2017 和 MS Build for .NET Core 的支持,一旦您意识到嵌套和转换构建命令不再需要成为项目的一部分。 不要再在 web.config 上使用 "Add Config Transforms" 命令,除非找到不会损坏项目文件的修复程序。只需手动添加 web.config 的转换版本,它们将自动嵌套并 运行 发布。是的 VS 2017!

以下内容,在您的 web.Release.config 中非常适合设置您的环境变量。

<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
  <location>
    <system.webServer>
      <aspNetCore>
        <environmentVariables>
          <environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Production" xdt:Locator="Match(name)" xdt:Transform="SetAttributes" />
        </environmentVariables>
      </aspNetCore>
    </system.webServer>
  </location>
</configuration>

此外,使用 .NET Core 2.2,您不再需要将额外的应用程序设置转换(关闭您的环境变量)添加到您的启动 class。这个默认...

    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

...自动处理已接受答案的代码。

底线是,作为一个毫无歉意的 Microsoft 开发人员,我仍然想假设我的应用程序只会发布到 IIS 服务器,使用 MS Build 和 Web Deploy,并且我希望能够配置我的应用程序通过应用程序自己的配置;我希望能够在 Build 上执行此操作,而不是作为发布或 post-publish 命令行命令。如果 Microsoft 或某人为 Visual Studio 创建了一个简单的构建插件,它将转换我的 appsettings.json 文件,那么我只发布给定环境所需的内容,我会很乐意使用它,但我还没有找到一个,或者有时间写一个,但是。

所以我确保直接回答 OP 的问题:AppSettings 可以很容易地从 web.config 转移到 appsettings.json,而且可能应该,只要你了解所有 appsettings.json 文件被发布,并在 运行 时确定,这与真正的转换解决方案不同,后者仅根据请求的配置文件发布必要的文件和设置。仅使用 web.config 转换来设置确定要使用哪个 appsettings.{env}.json 文件所需的环境变量。同样,如果我们可以按照 OP 的要求将我们的 apsettings.json 文件转换为与我们的 web.config 相同的方式,则整个讨论都按照 Dodo 的方式进行。我有预感总有一天它会到来,如果它还没有的话。

是的,从遗留的 .NET Framework 迁移到 .NET Core 可能是一个有趣的练习。 .NET Core 向前迈出了一大步,但还有一些障碍需要克服;特别是对于那些从一开始就继承遗产的人。

这是一个丑陋的解决方法:

在 Azure 构建管道中,构建 ASP.NET 核心项目后,将 appsettings.Production.json 文件复制到工件文件夹中的单独文件夹中。 在发布管道中,使用 'Replace tokens' 任务将 json 文件中的标记替换为发布变量。 将应用程序部署到 IIS 后,将 'transformed' appsettings.Production.json 复制到网站文件夹。

有效...