Azure 应用服务似乎在 .NET 5 模式下启用了 NLS
Azure App Service seems to have NLS enabled in .NET 5 mode
在花了无数个小时来深入了解错误的核心之后,我最终将问题归结为在 .NET 5 中使用 string.Compare
和 StringComparison.InvariantCultureIgnoreCase
。
考虑以下两个 dotnetfiddle:
- .NET 4.7.2:https://dotnetfiddle.net/KdErSK
- .NET 5:https://dotnetfiddle.net/ZWfprp
当 运行 .NET 4.7.2 时,结果为 -1,当 运行 .NET 5 时,结果为 1。
经过一些浏览,这导致了以下通知:
- https://docs.microsoft.com/en-us/dotnet/standard/base-types/string-comparison-net-5-plus
- https://docs.microsoft.com/en-us/dotnet/core/extensions/globalization-icu
因此,通过这种方式,-1 的结果是 NLS 版本,而 1 的 .NET 5 结果是 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 一边,那么我的问题是报告此事件的最佳位置是什么?
我认为你可以使用 this method 在 Azure 应用服务中启用 App-local ICU。
如果您的 Web 应用程序是依赖于框架的应用程序,您可以通过 NuGet 包使用 ICU。
- 在您的 web 应用程序 项目中安装 NuGet 包 Microsoft.ICU.ICU4C.Runtime。
- 编辑项目文件以在
<ItemGroup>
部分添加 <RuntimeHostConfigurationOption Include="System.Globalization.AppLocalIcu" Value="<suffix>:<version> or <version>" />
。或者您可以添加值为 <suffix>:<version>
或 <version>
. 的应用程序设置 DOTNET_SYSTEM_GLOBALIZATION_APPLOCALICU
那你就可以随意使用Azure App Service中的特殊版ICU了
Azure 应用服务团队的某个人对此进行了深入研究:
- 大多数 Azure 应用服务 运行 Windows 2016 年,更具体地说是在撰写本文时:
Major Minor Build Revision
----- ----- ----- --------
10 0 14393 0
- 在 Windows 服务器环境中,Windows Server 2019 中引入了 ICU。
所以回答我自己的问题:Azure 应用服务确实默认使用 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)。
我将接受我自己的回答,因为我觉得它可以更好地回答“为什么会这样”的问题,而不仅仅是修复它。
在花了无数个小时来深入了解错误的核心之后,我最终将问题归结为在 .NET 5 中使用 string.Compare
和 StringComparison.InvariantCultureIgnoreCase
。
考虑以下两个 dotnetfiddle:
- .NET 4.7.2:https://dotnetfiddle.net/KdErSK
- .NET 5:https://dotnetfiddle.net/ZWfprp
当 运行 .NET 4.7.2 时,结果为 -1,当 运行 .NET 5 时,结果为 1。
经过一些浏览,这导致了以下通知:
- https://docs.microsoft.com/en-us/dotnet/standard/base-types/string-comparison-net-5-plus
- https://docs.microsoft.com/en-us/dotnet/core/extensions/globalization-icu
因此,通过这种方式,-1 的结果是 NLS 版本,而 1 的 .NET 5 结果是 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 一边,那么我的问题是报告此事件的最佳位置是什么?
我认为你可以使用 this method 在 Azure 应用服务中启用 App-local ICU。
如果您的 Web 应用程序是依赖于框架的应用程序,您可以通过 NuGet 包使用 ICU。
- 在您的 web 应用程序 项目中安装 NuGet 包 Microsoft.ICU.ICU4C.Runtime。
- 编辑项目文件以在
<ItemGroup>
部分添加<RuntimeHostConfigurationOption Include="System.Globalization.AppLocalIcu" Value="<suffix>:<version> or <version>" />
。或者您可以添加值为<suffix>:<version>
或<version>
. 的应用程序设置
DOTNET_SYSTEM_GLOBALIZATION_APPLOCALICU
那你就可以随意使用Azure App Service中的特殊版ICU了
Azure 应用服务团队的某个人对此进行了深入研究:
- 大多数 Azure 应用服务 运行 Windows 2016 年,更具体地说是在撰写本文时:
Major Minor Build Revision
----- ----- ----- --------
10 0 14393 0
- 在 Windows 服务器环境中,Windows Server 2019 中引入了 ICU。
所以回答我自己的问题:Azure 应用服务确实默认使用 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)。
我将接受我自己的回答,因为我觉得它可以更好地回答“为什么会这样”的问题,而不仅仅是修复它。