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

14
我目前正在从.NET Framework转向.NET Core。过去,我的所有应用程序设置都在Web.config文件中。当我添加了一个新的发布配置文件时,我可以右键单击并选择“添加配置转换”,这将在Web.config下生成一个嵌套的Web.{Profile}.config文件,在其中我可以设置特定于相应配置文件的应用程序设置。
现在,对于.NET Core,我想使用appsettings.json文件而不是Web.config文件实现相同的效果。如何创建一个appsettings.{Profile}.json文件,它将嵌套在appsettings.json文件下,并包含特定于我的发布配置文件的设置?当然,我可以手动创建该文件,但是什么东西“链接”这些设置,使它们在应用程序发布时覆盖appsettings.json?在Visual Studio中是否有像我旧的.NET Framework项目描述的那样简单的方法?或者我漏掉了什么?
谢谢!
3个回答

18

但是是什么“链接”了这些设置,以便在应用程序发布时它们将替代 appsettings.json?

appsettings 是由 Program.cs 中的 WebHost 配置的。

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>();
在实现webhost.cs时,框架会将appsettings添加到webhost中。
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
      .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
第二行是将特定于环境的appsettings添加到代码中。在Visual Studio中,此环境变量定义在项目设置 -> 调试页面中,称为ASPNETCORE_ENVIRONMENT。默认情况下,它设置为Development,因此当您在Visual Studio内构建和运行时,将加载appsettings.development.json文件(如果存在),并覆盖appsettings.json文件中的任何匹配设置。
当您发布应用程序时,可以使用同名的操作系统环境变量覆盖此值。.NET Core从哪里读取值,并采用“后一个胜出”的策略。
目前的层次结构如下:
1. 文件(appsettings.json、appsettings.{Environment}.json,其中{Environment}是应用程序当前托管环境) 2. Azure密钥保管库 3. 用户机密(Secret Manager)(仅在开发环境中) 4. 环境变量 5. 命令行参数
因此,当您发布应用程序时,可以使用环境变量覆盖主机操作系统上的环境。当.NET Core启动已发布的应用程序时,它将读取该变量并加载相应的appsettings.{environment}.json文件。如果未设置该值或该环境不存在文件,则将应用appsettings.json中的设置。
您可以在此处了解有关ASPNETCORE_ENVIRONMENT设置的更多信息。

5
这很棒,我认为是正确的,但并没有真正回答如何替换web.config转换的问题。如果我的开发和多个测试环境都存在于同一台机器上,我该怎么做才能为每个HOST拥有一个唯一的操作系统级别的环境变量?我真的很想要一个实际的转换解决方案,可以在构建(或发布)时运行,而不是在运行时。 - iGanja
1
.Net Core 应用程序只需构建一次即可在任何地方运行,因此不再推荐使用 web.config 转换。请参见此答案以获取良好的描述。在您的多主机环境中,您可以使用命令行参数来覆盖该实例的 {environment} 值,并允许您为不同的实例使用不同的设置。 - Simply Ged
1
我可以在任何平台上理论上运行我的新型.NET Core应用程序,这是微软为了跟上时代潮流而推出的一个不错的营销策略,但实际上,大多数微软开发人员都知道他们要部署到哪个平台,很可能是IIS服务器。虽然我可以理解转换不再被“推荐”,但我确实需要一个像web.config转换一样简单的持续集成解决方案。 - iGanja
1
如果你只针对Windows平台开发,那么最好的选择是使用.Net Framework,因为它专门为Windows设计,并提供更大的Windows特定API接口。微软有一个页面可以帮助你选择要使用哪个框架。虽然.Net Core是“新玩具”,但并不总是最佳选择 :-) - Simply Ged
1
同意。虽然我发现转移到.NET Core有一些好处,即使在纯Windows环境下也是如此。正如你所说,我们失去了一些不错的Windows特定API,但我发现这迫使我们考虑其他平台,并以更为普遍的方式进行编程。还有,似乎总有一些开发经理觉得需要跟上最新的技术。 :^) - iGanja
完全同意你的看法,iGanja - 没有标准的工作流程 appsettings 转换文件是相当可悲的。这个功能似乎非常简单,可以遵循之前转换所做的相同指令和路径,并最终与发布配置集成,在选择适当的配置进行发布时使用。微软,加油! - Sean Haddy

6

......自从我的原始评论以来,我已经发现在 .NET Core 中,web.config 转换完全受到 VS 2017 和 MS Build 的支持,一旦你意识到嵌套和转换构建命令不再需要成为项目的一部分。除非你找到了一个不会破坏项目文件的修复方法,否则不要再使用 "Add Config Transforms" 命令在你的 web.config 上操作。只需手动添加你的 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中,您不再需要将额外的appsettings转换(关闭环境变量)添加到启动类中。这是默认...

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

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

底线是,作为一个毫不掩饰的微软开发者,我仍然希望假设我的应用程序只会发布到使用MS Build和Web Deploy的IIS服务器,并且我希望能够通过应用程序自己的配置来配置我的应用程序;并且我希望能够在构建时完成这些操作,而不是作为发布或后发布的命令行命令。如果微软或其他人创建了一个简单的Visual Studio构建插件,可以转换我的appsettings.json文件,以便我只发布给定环境所需的内容,我会很乐意使用它,但我还没有找到一个,或者有时间去编写一个。

只要您理解所有的appsettings.json文件都是在运行时确定并发布的,而不像真正的转换解决方案那样只发布必要的文件和设置,取而代之地是使用web.config转换来设置必要的环境变量,以确定要使用哪个appsettings.{env}.json文件。如果我们能够像OP所请求的那样转换我们的apsettings.json文件,就像我们转换我们的web.config一样,这整个讨论将不复存在。 我有预感,如果还没有的话,总有一天它会出现。

是的,从传统的.NET Framework迁移到.NET Core可能是一项有趣的练习。.NET Core是一个巨大的进步,但是对于那些一直在使用传统.NET Framework的人来说,还有一些障碍需要克服。


@Toolkit - 可能有用。VS 有一个转换插件,可以将任何(其他)基于 XML 的文件(如 app.config)进行转换。该插件名为 Configuration Transform,由 Golan Avraham 开发。 https://marketplace.visualstudio.com/items?itemName=GolanAvraham.ConfigurationTransform - iGanja
这是一篇有趣的2020年文章,来自微软,介绍如何在Core 3.1中使用Web.config:https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/iis/transform-webconfig?view=aspnetcore-3.1 - Yogi

0

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

在 Azure 构建管道中,在构建 ASP.NET Core 项目后,将 appsettings.Production.json 文件复制到工件文件夹中的单独文件夹中。 在发布管道中,使用“替换令牌”任务来使用发布变量替换该 json 文件中的令牌。 在将应用程序部署到 IIS 后,将“转换后”的 appsettings.Production.json 复制到网站文件夹中。

它有效...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接