dotnet publish 有时会将 appsettings.Development.json 复制为 appsettings.development.json
Posted
技术标签:
【中文标题】dotnet publish 有时会将 appsettings.Development.json 复制为 appsettings.development.json【英文标题】:dotnet publish sometimes copying appsettings.Development.json as appsettings.development.json 【发布时间】:2017-10-02 17:56:49 【问题描述】:一般来说,.NET Core 环境变量的大小写敏感性一直是一场噩梦,尤其是当你开始使用 .NET Core 位运行 Docker 容器时,现在我发现它又抬起了丑陋的脑袋,这是一个 dotnet 发布输出截图:
这里是 appsettings 文件的源代码:
这是 Visual Studio 中的文件名:
使用 git 我可以证明开发中的“D”确实是 Windows 文件名的大写:
现在这个问题也发生在我的 appsettings.Production.json 和 appsettings.Staging.json 中。它是间歇性的。有时,dotnet publish 会尊重大小写,将构建工件复制到其发布文件夹,但有时它会将我的一些 appsettings.json 文件的环境首字母小写。
当我在我的机器上开发时,我可以删除发布文件夹来解决问题,但是一旦我进入我的 Linux 构建服务器并且 dotnet 发布发生在完全干净的 Linux 平板上,在 dotnet 发布执行之前不存在发布文件夹我仍然间歇性地遇到同样的问题。
另外,只是想指出 .NET Core IHostingEnvironment.IsDevelopment()
方法是区分大小写的,我不敢相信,但是将我的代码设置为忽略大小写更具挑战性,因为如果另一个开发者信任 IHostingEnvironment.IsDevelopment()
,这是一个常见的 .NET Core 约定:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
if (env.IsDevelopment() || env.EnvironmentName.ToLower() == "localhost")
app.UseDeveloperExceptionPage();
app.UseServiceStack(new AppHost());
我至少可以这样做,以缓解这个案例问题:
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.env.EnvironmentName.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.env.EnvironmentName.ToLower().json", optional: true, reloadOnChange: true);
但再次参考 .NET Core 约定,环境大小写敏感性这仍然在我上面提到的开发人员使用IHostingEnvironment.IsDevelopment()
的计划中留下了一个“漏洞”
【问题讨论】:
【参考方案1】:IHostingEnvironment.EnvironmentName
只是一个字符串属性,它同时具有公共 getter 和 setter。作为开发人员,您可以完全控制它包含的值。在大多数实际情况下,它只返回与 ASPNETCORE_ENVIRONMENT 变量中相同的值。
基于HostingEnvironmentExtensions.cs 实现:
env.IsDevelopment
在内部使用相同的IHostingEnvironment.EnvironmentName
来获取环境名称,但是是的,将其与包含“开发”作为值的EnvironmentName.Development
进行比较。
一般来说,您可以使用IHostingEnvironment.IsEnvironment
方法获取预期的环境名称作为第二个参数。
作为示例,以下代码产生不区分大小写的结果:
// IHostingEnvironment env;
env.EnvironmentName = env.EnvironmentName.ToLower();
var result = env.IsEnvironment(EnvironmentName.Development.ToLower());
关于文件,您可以执行以下操作:
将所有配置文件重命名为小写,例如appsettings.production.json
修改您的代码以仅使用小写的环境名称:
.AddJsonFile("appsettings.env.EnvironmentName.ToLower().json")
【讨论】:
是的,解决了部分问题,不过我最近刚刚添加到我的问题中,在我看到你回答之前,IHostingEnvironment.IsDevelopment() 仍然存在漏洞,阅读底部的更新我的问题是关于你的答案的一次捕获【参考方案2】:我想提供 EnvironmentHelper
类,我创建该类是为了在我的所有 API 中帮助解决这个问题,以防其他人发现它有帮助:
public static class EnvironmentHelper
public static bool IsLocalhost(string env)
return IsEnvironment(env, EnvironmentName.Localhost);
public static bool IsDevelopment(string env)
return IsEnvironment(env, EnvironmentName.Development);
public static bool IsStaging(string env)
return IsEnvironment(env, EnvironmentName.Staging);
public static bool IsProduction(string env)
return IsEnvironment(env, EnvironmentName.Production);
private static bool IsEnvironment(string env, string environmentName)
return string.Equals(env, environmentName, StringComparison.CurrentCultureIgnoreCase);
public static class EnvironmentName
public static readonly string Localhost = "Localhost";
public static readonly string Development = "Development";
public static readonly string Staging = "Staging";
public static readonly string Production = "Production";
【讨论】:
以上是关于dotnet publish 有时会将 appsettings.Development.json 复制为 appsettings.development.json的主要内容,如果未能解决你的问题,请参考以下文章
使用 dotnet publish 发布多个 web.config
“dotnet publish”命令行跳过部署到 Azure Functions