【问题标题】:How to update appsettings.json based on publish profile using .NET Core?如何使用 .NET Core 根据发布配置文件更新 appsettings.json?
【发布时间】:2018-11-16 01:58:11
【问题描述】:

我目前正在从 .NET Framework 切换到 .NET Core。过去,我所有的应用程序设置都在 Web.config 文件中。当我添加一个新的发布配置文件时,我可以右键单击并选择“添加配置转换”,这将在 Web.config 下生成一个嵌套的 Web.{Profile}.config 文件,我可以在其中设置特定于相应配置文件的应用程序设置。

现在,在 .NET Core 中,我想使用 appsettings.json 文件而不是 Web.config 文件来实现相同的效果。如何创建 appsettings.{Profile}.json 文件,该文件将嵌套在我的 appsettings.json 文件下并包含特定于我的发布配置文件的设置?当然,我可以手动创建文件,但什么是“链接”设置以便在应用程序发布时它们将覆盖 appsettings.json?有没有像我为旧的 .NET Framework 项目描述的那样在 Visual Studio 中执行此操作的简单方法?还是我错过了什么?

谢谢!

【问题讨论】:

    标签: visual-studio asp.net-core .net-core asp.net-core-mvc appsettings


    【解决方案1】:

    但是是什么“链接”设置以便它们将覆盖 appsettings.json 什么时候发布应用?

    appsettings由WebHostProgram.cs中配置

    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 中,此环境变量在 Project Settings -&gt; Debug 页面中定义,称为 ASPNETCORE_ENVIRONMENT。默认情况下,它设置为 Development,因此当您在 Visual Studio 中构建和运行时,appsettings.development.json 文件(如果存在)将被加载并覆盖 appsettings.json 文件中的任何匹配设置。

    当您发布应用程序时,您可以使用同名的操作系统环境变量覆盖此值。 .NET Core 从哪里读取值有一个层次结构,并且有一个“最后一个获胜”策略。

    目前的层次结构是:

    1. 文件(appsettings.json、appsettings.{Environment}.json,其中 {Environment} 是应用的当前托管环境)
    2. Azure 密钥库
    3. 用户机密(机密管理器)(仅在开发环境中)
    4. 环境变量
    5. 命令行参数

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

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

    【讨论】:

    • 这很好,我认为是正确的,但并没有真正回答如何替换 web.config 转换的问题。如果我的开发环境和多个测试环境都存在于同一台机器上怎么办?如何为每个主机拥有一个唯一的操作系统级环境变量?我真的很想要一个适用于构建(或发布)而不是运行时的实际转换解决方案。
    • .Net Core 应用程序在任何地方运行一次即可构建,因此不再推荐使用 web.config 转换。有关详细说明,请参阅 this answer。在您的多主机环境中,您可以使用命令行参数来覆盖该实例的 {environment} 值,并允许您为不同的实例使用不同的设置
    • 理论上我可以在任何平台上运行我喜欢的新 .NET Core 应用程序这一事实是微软为了跟上琼斯的步伐而推出的一个不错的营销噱头,但实际上,大多数微软开发人员都知道这个平台他们将部署到它可能是一个 IIS 服务器。虽然我可以理解不再“推荐”转换,但我确实需要一个像 web.config 转换一样简单的持续集成解决方案。
    • 如果您只针对 Windows,那么最好的选择是坚持使用纯粹为 Windows 设计的 .Net Framework,并提供更大的 Windows 特定 API 界面。 Microsoft 有a page 可以帮助您选择要使用的框架。尽管 .Net Core 是“闪亮的新玩具”,但它并不总是最佳选择 :-)
    • 同意。尽管我发现迁移到 .NET Core 有一些不错的优势,即使在纯 Windows 环境中也是如此。正如你所说,我们确实失去了一些不错的 Windows 特定 API,但我发现它迫使我们转而考虑还有其他平台,以及如何以更不可知的方式进行编程。那似乎总有一些开发经理觉得无论如何都需要最新的[最伟大]。 :^)
    【解决方案2】:

    ...自从我最初发表评论以来,我发现 VS 2017 和 MS Build for .NET Core 完全支持 web.config 转换,一旦您意识到嵌套和转换构建命令不需要不再是项目的一部分。 不要再在您的 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 转换(关闭您的环境变量)添加到您的 Startup 类。这个默认...

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

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

    底线是,作为一个毫无歉意的 Microsoft 开发人员,我仍然想假设我的应用程序只会使用 MS Build 和 Web Deploy 发布到 IIS 服务器,并且我希望能够通过应用程序自己的配置;我希望能够在 Build 上执行此操作,而不是作为发布或发布后命令行命令。如果 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 向前迈出了一大步,但还有一些障碍需要克服;特别是对于那些从一开始就继承遗产的人。

    【讨论】:

    【解决方案3】:

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

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

    有效...

    【讨论】:

      猜你喜欢
      • 2017-06-23
      • 1970-01-01
      • 2018-04-05
      • 1970-01-01
      • 1970-01-01
      • 2018-03-19
      • 1970-01-01
      • 2021-04-24
      • 1970-01-01
      相关资源
      最近更新 更多