如何在.Net Core应用程序中发布特定于环境的appsettings?

98

我在我的 .Net Core 应用程序中有 3 个针对不同环境的 appsettings 文件。

enter image description here

project.json 中,我设置了 publishOptions 如下所示(根据此处的建议here)。

"publishOptions": {
    "include": [
      "wwwroot",      
      "appsettings.development.json",
      "appsettings.staging.json",
      "appsettings.production.json",
      "web.config"
    ]
  },

我有三个相应的启动类,根据环境使用适当的appsettings

var builder = new ConfigurationBuilder()
    .SetBasePath(env.ContentRootPath)
    .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: false, reloadOnChange: true);

然而,当我发布应用程序时,所有三个appsettings文件都会出现在所有环境中。如何发布特定于环境的appsetting文件?


27
请问有人能回答这个问题吗?把所有的 appsettings.json 文件发布到所有环境中真的没有意义。 - LP13
只要您在Windows上托管,就没有问题,但如果您切换到区分大小写的操作系统(*nix),那么就会出现问题。例如,微软的EnvironmentName字符串采用PascalCase格式。 - Granger
3
你找到解决方案了吗?我正在使用asp.netcore 3.1。 - fiberOptics
1
并不是真的。目前我的PowerShell脚本会复制整个发布文件夹,然后删除不需要的appsettings。请注意,即使您不删除appsettings,您的应用程序也不会使用所有。您的应用程序将仅使用appsettings.jsonappsettings.{environmentname}.json。在启动时加载文件的顺序在这里非常重要。 - LP13
3
我对.NET Core中缺少的所有基本功能感到非常厌烦,这使得它难以被认真对待。 - Scott Wilson
17个回答

1

一种可能的方法是运行预发布或发布后脚本/命令,例如通过运行执行dotnet publish-iis的gulp任务(或者在scriptsprepublish部分中使用一个任务在发布之前复制文件)。

在项目的project.json文件中添加以下内容:

"scripts": {
  "postpublish": [ "gulp cleanconfig", "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ]
}

您也可以在此处运行cmd或shell命令。但实际上,在第一次操作时不应有任何理由这么做,只需将所有3个appconfig文件一起发送即可。因为在Azure App Service上,您可以根据环境变量切换模式,这是通过Azure Portal进行调节的,而在发布时,staging和production slots将会被互换,但环境变量保持不变。
尽管如此,您不应该在appsettings.json中存储秘密信息(我想您是这样做的,并且这也是您想删除文件的原因)。相反,使用“用户密码”进行开发,并使用环境变量为生产设置连接字符串等等。特别是在Azure App Services和Docker容器中,它可以完美地工作。

5
我的appsettings没有任何秘密,但我们的连接字符串不同于每个环境,在appsettings中。我认为在appsettings中放置连接字符串并没有问题。我真的不明白为什么我要费尽心思来发布特定于环境的appsettings。事实上,这应该是发布过程的标准行为。我不认为任何人都希望所有的appsettings文件都出现在所有的环境中。我认为我们在这里遗漏了某些东西... - LP13
2
如果连接字符串中包含用户名和密码或API密钥,则属于机密信息。如果没有,那么公开这3个文件也不会有任何影响。具体问题是什么? - Tseng
2
它没有用户ID/密码。而且,appsetting文件实际包含的数据与问题无关。 - LP13
3
最终我使用了 Powershell 脚本来复制文件。在脚本中,我有根据环境复制 appsetting 文件的逻辑。 - LP13
我曾经参与过的许多系统在安全性方面都不允许部署不必要的文件,无论这给我带来多大的麻烦。此外,大型项目通常有5个或更多的环境:开发环境、集成测试环境、系统测试环境、用户验收测试环境、暂存环境、生产环境,有时还会有生产环境的镜像以及其他环境(演示环境等)。 - undefined
显示剩余6条评论

0
迄今为止我找到的最简单的方法是,在部署完成后部署所有配置文件,然后删除额外的文件。只需在部署脚本的末尾添加几行额外的代码即可。

0

我使用了这个NuGet包来解决这个问题:https://github.com/Microsoft/slow-cheetah/blob/master/doc/transforming_files.md

安装和使用所有配置都非常简单,只需在活动解决方案配置中进行设置(在我的情况下-我添加了一个新的“测试”配置以进行测试部署)。

之后,您可以在VS中安装此扩展程序:https://marketplace.visualstudio.com/items?itemName=vscps.SlowCheetah-XMLTransforms

现在,您可以使用此工具(如手册中所述)为VS中的.xml或.json应用程序配置设置创建新的配置子文件。例如,我有Debug、Test、Release文件(appsettings.Debug.json等)

下一步是为每个配置设置发布配置文件,并在发布后仅获得一个包含所有必要转换的文件。

转换类似于.net core Web应用程序中的经典.json环境转换。


0

针对使用.csproj的版本进行更新

首先,在.csproj文件中添加以下内容,以确保在发布期间将appsettings.json包含在发布目录中。

  <ItemGroup>
    <None Include="appsettings.json" CopyToPublishDirectory="Always" />
  </ItemGroup>

然后更新 Startup.cs 包含:

public Startup(IHostEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile($"appsettings.json", optional: true, reloadOnChange: true)
            .AddEnvironmentVariables();

        Configuration = builder.Build();
    }

0

针对 Dotnet 7,根据发布配置使用不同的 appsettings.json(即具有 2 个 Azure 发布目标:开发和生产):

  1. 为每个不同的发布配置创建 appsettings.(环境名称).json 文件。例如:appsettings.Development.json、appsettings.Production.json。

  2. 在你的发布配置中(位于 Properties\PublishProfiles 中的 .pubxml 文件),通过在 PropertyGroup 中添加 EnvironmentName,将发布配置名称指定为环境名称(例如 Development 或 Production):

    pubxml 文件中的 XML 格式如下:

     <PropertyGroup>
     <EnvironmentName>Production</EnvironmentName>
     </PropertyGroup>
    
  3. 默认情况下,asp.net core 将加载 appsettings.(环境名称).json 文件。 (更多信息请参见此处)

    1. 要测试当前所处的环境,可以使用以下代码:

      Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ??
      Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT") ?? "Production";
      

这是基于微软文档的


问题是如何阻止将appsettings.<environment>.json文件发布到其他环境而不是正在发布的环境。 - undefined

-1
去Program.cs,然后添加WebApplicationOptions。
var webAppOptions = new WebApplicationOptions()
{
    Args = args,

#if PRODUCTION
    EnvironmentName = Environments.Production,
#elif STAGING
    EnvironmentName = Environments.Staging,
#elif DEVELOPMENT
    EnvironmentName = Environments.Development,
#else
    EnvironmentName = Environments.Development,
#endif

};
var builder = WebApplication.CreateBuilder(webAppOptions);

1
这与问题无关。 - undefined
这与问题无关吗?这是这个问题的最佳解决方案。 - undefined
问题是在问所有3个appsettings文件都出现在所有环境中,这是关于发布的。例如,当发布到测试环境时,他们不希望appsettings.Development.json被发布到测试输出目录等。 - undefined

-4
说实话,我认为这不是构建流水线的正确任务。而且,dotnet cli 的发布功能非常有限。像 Tseng 给你展示的那样,去使用外部工具吧。部署是另一个领域,其复杂性与构建不同。
除了使用外部工具,dotnet cli 没有内置的构建方式!

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