【问题标题】:dotnet publish sometimes copying appsettings.Development.json as appsettings.development.jsondotnet publish 有时会将 appsettings.Development.json 复制为 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() 的计划中留下了一个“漏洞”

【问题讨论】:

    标签: .net asp.net-core .net-core


    【解决方案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";
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-13
      • 1970-01-01
      • 1970-01-01
      • 2018-02-27
      • 1970-01-01
      相关资源
      最近更新 更多