vb.netstartswith

Why does StartsWith("⏸") return true when the string is "<mn" in ASP.NET but not in desktop apps?


I'm experiencing an inconsistent behavior between a desktop .NET application and a web-based ASP.NET application (running under Visual Studio).

In both, I use the same regular expression:

Dim mStart As Match = Regex.Match(s, "^((<|⏸)(?<tag>\w+)|\(|⸨)")

Then I evaluate:

If mStart.Groups("tag").Success Then
  If mStart.Value.StartsWith("⏸") Then
    ' Unexpectedly true in ASP.NET when mStart.Value = "<mn"
  End If
End If

In the desktop version, the condition is correctly false because mStart.Value is "<mn", and the first character is ASCII 60 (<).

In the ASP.NET version, mStart.Value is also "<mn" (Length = 3), and AscW(mStart.Value(0)) = 60, yet StartsWith("⏸") returns True, which is unexpected.

Additional detail:

In a previous execution of the same method, the input string s did start with "⏸mn", which correctly triggered the condition. But in a later call, when the string s = "<mn", the condition StartsWith("⏸") still evaluates to True, even though the first character is <.

What I’ve verified:

mStart.Value = "<mn"

mStart.Value.Length = 3

AscW(mStart.Value(0)) = 60

There are no invisible characters or leading BOMs in the string.

A character-by-character loop shows the first character is definitely <.

Hypotheses I considered:

Unicode normalization

String caching or reuse in Regex.Match

Hidden character due to HTML/XML decoding

Differences in Regex.Match().Value handling between ASP.NET and desktop .NET

Has anyone encountered anything similar? Could this be a bug, caching issue, or platform-specific behavior?

Any insights would be greatly appreciated.


Solution

  • It seems to be something to do with the way strings are compared using cultures.

    In a simple console app, this outputs "FAIL":

    Dim s = "<"
    
    If s.StartsWith("⏸", StringComparison.CurrentCulture) Then
        Console.WriteLine("FAIL.")
    End If
    
    Console.ReadLine()
    

    Whereas this does not:

    Dim s = "<"
    
    If s.StartsWith("⏸", StringComparison.Ordinal) Then
        Console.WriteLine("FAIL.")
    End If
    
    Console.ReadLine()
    

    Solution: use StringComparison.Ordinal or StringComparison.OrdinalIgnoreCase.

    Although, when I tried it with .NET 4.8.1 in ASP.NET and a console app, Threading.Thread.CurrentThread.CurrentUICulture.Name (and CurrentCulture.name) was "en-GB" in both cases.