Azure App Service 在 .NET 5 模式下似乎启用了 NLS。

9
花费无数个小时研究一个bug后,我最终将问题归结为在.NET 5中使用string.CompareStringComparison.InvariantCultureIgnoreCase。考虑以下两个dotnetfiddles:NET 4.7.2:https://dotnetfiddle.net/KdErSK,NET 5:https://dotnetfiddle.net/ZWfprp。在运行.NET 4.7.2时,结果为-1,在运行.NET 5时,结果为1。 经过一些浏览,我发现了以下公告:https://learn.microsoft.com/en-us/dotnet/standard/base-types/string-comparison-net-5-plushttps://learn.microsoft.com/en-us/dotnet/core/extensions/globalization-icu。因此,按照这个说法,-1是NLS版本的结果,而.NET 5的结果1是ICU版本的结果。 然而,当我在.NET 5模式下启动Azure应用服务时,在Razor页面中上述代码的结果为-1,即NLS版本。这可能会导致各种奇怪的问题,因为两个不同的系统会导致意外的结果。 当我在项目文件中添加如下内容时(正如最后一篇文章中所提到的),我的本地环境也输出了-1。
<ItemGroup>
  <RuntimeHostConfigurationOption Include="System.Globalization.UseNls" Value="true" />
</ItemGroup>

无论我使用什么配置在Azure中,它总是输出-1。
长话短说,Azure出了些问题。根据文档,我的Windows版本已经足够新,启用了ICU。看起来Azure应用服务要么使用了强制NLS模式,要么正在运行一些本地机器没有的ICU版本。
有人知道如何找出Azure正在使用哪个ICU版本(如果有的话),这样我就可以按照文档建议使用AppLocalIcu了吗?否则,如果明显是Azure方面的问题,则我的问题是要报告最好的位置是什么?

我会将此提交到Github并获取权威答案,如果有错误,他们很可能会修复它,或者公开让其他人修复并进行拉取请求。 - TheGeneral
@TheGeneral 那个GitHub库最适合这个问题?我考虑使用dotnet,但似乎这是一个Azure问题,而不是.NET本身的问题。 - Lennard Fonteijn
2个回答

8

Azure 应用服务团队中的某人已经深入研究了这个问题:

  • 大多数 Azure 应用服务运行在 Windows 2016 上,更具体地说,在撰写本文时:
Major  Minor  Build  Revision
-----  -----  -----  --------
10     0      14393  0   
  • 在Windows Server 2019中引入了ICU。

因此,回答我的问题:Azure App Services默认情况下确实使用NLS。这不是一个错误!

通过在项目文件中包含以下内容,将强制使用ICU:

<ItemGroup Condition="'$(OS)' == 'Windows_NT'">
  <PackageReference Include="Microsoft.ICU.ICU4C.Runtime" Version="68.2.0.9" />
  <RuntimeHostConfigurationOption Include="System.Globalization.AppLocalIcu" Value="68.2" />
</ItemGroup>

这与@Crazy Crab提出的解决方案一致,谢谢!

还可以查看https://www.nuget.org/packages/Microsoft.ICU.ICU4C.Runtime 获取最新版本(本文写作时为68.2.0.9)。

我将接受自己的答案,因为我认为它对于“为什么会发生这种情况”这个问题给出了更好的答案,而不仅仅是修复它。


3
FYI似乎仍然是这种情况——今天我们在Azure应用服务上遇到了这个问题。 - IGx89
2
非常有帮助的回答。一个考虑因素:如果您正在使用Linux主机(例如GitHub动作)构建,请移除ItemGroup上的Condition - Donnie Hale

3
我认为你可以使用这种方法来在Azure应用服务中启用App-local ICU。
如果你的Web应用程序是基于框架的应用程序,你可以通过NuGet包来使用ICU。
请在您的Web应用程序项目中安装NuGet包Microsoft.ICU.ICU4C.Runtime,并编辑项目文件以在<ItemGroup>部分添加<RuntimeHostConfigurationOption Include="System.Globalization.AppLocalIcu" Value="<suffix>:<version> or <version>" />。或者您可以添加一个名为DOTNET_SYSTEM_GLOBALIZATION_APPLOCALICU的应用设置,其值为<suffix>:<version><version>
然后,您可以像想要的那样在Azure App Service中使用特殊版本的ICU。

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