skip to Main Content

I have an ASP.Net Core Project with an MVC configuration. I use ASP.Net Core Version 5.0
My native language is german and therefore our database is also filled with german words, for example the word "fußball" (which means football or soccer, depending on where you are from).

As you can see, this word has an ß. In german, this "ß" is basically equivalent to "ss". Therefore if I have the string "fußball" I want to be able to find it if someone searches for "fussball" also.

I understand that ASP.Net Core has good localization and globalization options, I just can’t seem to figure this one out.

Consider the following code:

var currCulture = CultureInfo.CurrentCulture.Name; // = "de-AT"

var str1 = "fußball";
str1.StartsWith("fuss"); //returns false
str1.StartsWith("fuss", StringComparison.InvariantCulture); //returns false
String.Equals("ß", "ss", StringComparison.InvariantCulture); //returns false

since I use my Windows-PC in an english language and I read in another Stackoverflow question that the CultureInfo is dependent on the operating system, I decided to insert the following into my Startup.cs-File, as suggested in this Stackoverflow question

var cultureInfo = new CultureInfo("de-AT"); //de-AT for Austria, i tried with de-DE too for germany, but the result was the same
cultureInfo.NumberFormat.CurrencySymbol = "€";

CultureInfo.DefaultThreadCurrentCulture = cultureInfo;
CultureInfo.DefaultThreadCurrentUICulture = cultureInfo;

unfortunately, with my current setup, it always tells me that "ß" and "ss" are not the same when comparing them in strings. The same goes for "ä" and "ae", but I need these to be found in the same way. Regardless of if the input is "ä"/"ae" or "ß"/"ss".

Any ideas what I’ve been doing wrong are greatly appreciated, I just can’t seem to get this to work.

Thank you in advance & best regards!

2

Answers


  1. .NET Core on Windows had used the OS’s built-in NLS localisation library, whereas other operating systems used the cross-platform and standard-compliant ICU library. Because NLS and ICU differ in implementation, this meant that the same .NET Core program could produce different results on different platforms when comparing strings.

    To prevent this confusion, from .NET 5 the decision was made to use ICU for all platforms, including Windows. However, since many apps (yours included) are written on Windows and thus assume that string comparisons work in the NLS way, there are some things you need to do to make them work as expected with ICU.

    In your case, you can explicitly set the CurrentCulture then ensure you explicitly use it in string comparisons:

    using System.Globalization;
    
    CultureInfo.CurrentCulture = new CultureInfo("de-AT", false);
    Console.WriteLine($"CurrentCulture is {CultureInfo.CurrentCulture.Name}.");
    
    string first = "Sie tanzen auf der Straße.";
    string second = "Sie tanzen auf der Strasse.";
    
    bool b = string.Equals(first, second, StringComparison.CurrentCulture);
    Console.WriteLine($"The two strings {(b ? "are" : "are not")} equal.");
    
    // CurrentCulture is de-AT.
    // The two strings are equal.
    

    By placing the following in your .csproj you can revert to NLS if ICU causes too many issues for your application, but this should only really be used while you are upgrading your code to work with ICU:

      <ItemGroup>
          <RuntimeHostConfigurationOption Include="System.Globalization.UseNls" Value="true" />
      </ItemGroup>
    
    Login or Signup to reply.
  2. As @chadnt’s answer described NET5 introduced a breaking change that causes this problem.

    Here I found another solution which works even with NET6/7.

    string sb = "ß";
    string ss = "ss";
    
    StringComparer sc1 = StringComparer.Create(CultureInfo.CurrentCulture, CompareOptions.IgnoreNonSpace);
    Console.WriteLine(sc1.Compare(sb, ss));
    //returns 0 - zero means sb a ss are equal; 
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search