Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Azure App Service seems to have NLS enabled in .NET 5 mode

After spending countless of hours on getting to the core of a bug, I eventually boiled down a problem to the use of string.Compare with StringComparison.InvariantCultureIgnoreCase in .NET 5.

Consider the following two dotnetfiddles:

  • .NET 4.7.2: https://dotnetfiddle.net/KdErSK
  • .NET 5: https://dotnetfiddle.net/ZWfprp

When running the .NET 4.7.2 you get -1 as a result, when running .NET 5 you get 1 as a result.

After some browsing, this led to the following notice:

  • https://learn.microsoft.com/en-us/dotnet/standard/base-types/string-comparison-net-5-plus
  • https://learn.microsoft.com/en-us/dotnet/core/extensions/globalization-icu

So, going by this, a result of -1 is the NLS version, whereas the .NET 5 result of 1 is the ICU version.

However, when I spin up an Azure App Service in .NET 5 mode, the result of the above code in a Razor page is -1, AKA: the NLS version.

This can cause all kinds of weird issues, because two different systems lead to unexpected results.

When I add add the following to my project-file, as mentioned in the last article, my local environment also outputs a -1.

<ItemGroup>
  <RuntimeHostConfigurationOption Include="System.Globalization.UseNls" Value="true" />
</ItemGroup>

No matter what kind of configuration I use in Azure, it will always keep outputting -1.

Long story, something is up on Azure. As per documentation, my Windows version is new enough to have ICU enabled. Looks like the Azure App Service is either using a forced NLS mode, or is running some ICU version my local machine doesn't have.

Anyone know how I can figure out which ICU version (if any) Azure is using, so I can use the suggestion from the documentation to use a AppLocalIcu? Otherwise, if something is clearly on the side of Azure, then my question is what the best location would be to report this?

like image 628
Lennard Fonteijn Avatar asked Aug 31 '21 22:08

Lennard Fonteijn


People also ask

Does Azure support .NET Core 5?

Microsoft this month announced its Azure Functions -- for serverless cloud computing -- now supports . NET 5, an umbrella offering that followed the . NET Core series of open source, cross-platform releases, which supplanted the old . NET Framework.

Does Azure App Service Support .NET 6?

Azure App Service for . NET 6 is generally available now, meaning application developers can utilize the capabilities offered by . NET 6, and run those web apps in App Service.

Does Azure App Service use Kestrel?

Yes, when you publish to Azure Web Services, IIS is used to host your application. As you said, it acts as a reverse proxy to your application, which is running Kestrel HTTP server.

Will my Azure App service run on Microsoft Azure NET 5?

It should, if all things have gone well, run .NET 5 on your Azure App Service. The new app is up and hosted in Azure, running .NET 5. To re-iterate, we have now:

How to check the supported NET Framework version in Azure App service?

In App Service, the Windows instances already have all the supported.NET Framework versions installed. To show the.NET Framework runtime and SDK versions available to you, navigate to https://<app-name>.scm.azurewebsites.net/DebugConsole and run the appropriate command in the browser-based console:

Does Azure App services support new releases of NET Core?

This was the approach required for new releases of .NET Core on Azure App Services prior to .NET 5, and it continues to be supported today. Much appreciated! Everything was fine on .NET Core 3.1, I've updated to .NET 5 and the app service is broken. I've been trying to figure out what's causing the issue, digging through logs and diagnostic tools.

How do I upgrade an existing app service via Azure portal?

To do this via the Azure Portal for an existing App Service, complete the following steps: 1 Go to the App Service you want to upgrade 2 Click on Configuration on the left-hand navigation 3 Click on General Settings in the page-level navigation 4 Under Stack Settings, select .NET 5 Under Framework Version, select .NET 5 More ...


2 Answers

Someone at the Azure App Service team dove into this:

  • Most Azure App Services run on Windows 2016, more specifically at the time of writing:
Major  Minor  Build  Revision
-----  -----  -----  --------
10     0      14393  0   
  • In the Windows Server landscape ICU was introduced in Windows Server 2019.

So to answer my own question: Azure App Services are indeed using NLS by default. This is not a bug!

By including the following in your project-file, ICU will be forced:

<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>

This is in line with the solution that @Crazy Crab mentioned, thanks!

Also see https://www.nuget.org/packages/Microsoft.ICU.ICU4C.Runtime for the latest version (68.2.0.9 at the time of writing).

I'm going to accept my own answer, as I feel it gives a better answer to the "Why is this happening" question, rather than just fixing it.

like image 95
Lennard Fonteijn Avatar answered Oct 19 '22 08:10

Lennard Fonteijn


I think you can use this method to enable the App-local ICU in the Azure app service.

If your web app is a framework-dependent application, you can consume ICU via a NuGet package.

  • Install the NuGet package Microsoft.ICU.ICU4C.Runtime in your web app project.
  • Edit the project file to add <RuntimeHostConfigurationOption Include="System.Globalization.AppLocalIcu" Value="<suffix>:<version> or <version>" /> in the section <ItemGroup>. Or you can add an app setting DOTNET_SYSTEM_GLOBALIZATION_APPLOCALICU with the value <suffix>:<version> or <version>.

Then you can use the special version of ICU in the Azure App Service as you want.

like image 33
Crazy Crab Avatar answered Oct 19 '22 09:10

Crazy Crab