runtime: Assembly.GetType("System.Net.Http.HttpClientHandler", false, true) does not find type but finds it when ignoreCase is set to false

Description

When trying to do GetType with ignorecase as true does not find the type but finds it when ignoreCase is set to false.

This only happens in .NET7 preview 1 and does not happen in .NET 6.

PowerShell team is using the type in PowerShellGet and it fails to register the endpoint as the type is not found.

Reproduction Steps

Sample program:

public static void Main(string[] args) {

        //string assemblyName = "System.Net.Http.dll";
        //string typeName = "System.Net.Http.HttpClientHandler";
        string assemblyName = args[0];
        string typeName = args[1];

        var myLocation = Path.GetDirectoryName(Assembly.GetEntryAssembly()?.Location);

        string assemblyPath = Path.Join(myLocation, assemblyName);
        var assembly = System.Reflection.Assembly.LoadFile(assemblyPath);

        var typeWithCaseIgnore = assembly.GetType(typeName, throwOnError: false, ignoreCase: true);
        if (typeWithCaseIgnore is null) {
            Console.WriteLine("Type NOT found with: assembly.GetType(typeName, throwOnError: false, ignoreCase: true)");
        }
        else {
            Console.WriteLine($"Type found with assembly.GetType(typeName, throwOnError: false, ignoreCase: true): {typeWithCaseIgnore.FullName} ");
        }

        var typeWithoutCaseIgnore = assembly.GetType(typeName, throwOnError: false, ignoreCase: false);
        if (typeWithoutCaseIgnore is null) {
            Console.WriteLine("Type NOT found with: assembly.GetType(typeName, throwOnError: false, ignoreCase: false)");
        }
        else {
            Console.WriteLine($"Type found with assembly.GetType(typeName, throwOnError: false, ignoreCase: false): {typeWithoutCaseIgnore.FullName} ");
        }
    }

Output:

HelloWorld.exe System.Net.Http.dll System.Net.Http.HttpClientHandler Type NOT found with: assembly.GetType(typeName, throwOnError: false, ignoreCase: true) Type found with assembly.GetType(typeName, throwOnError: false, ignoreCase: false): System.Net.Http.HttpClientHandler

But for some other type it works:

HelloWorld.exe System.Xml.dll System.Xml.XmlTextReader Type found with assembly.GetType(typeName, throwOnError: false, ignoreCase: true): System.Xml.XmlTextReader Type found with assembly.GetType(typeName, throwOnError: false, ignoreCase: false): System.Xml.XmlTextReader

Expected behavior

System.Net.Http.HttpClientHandler is found

Actual behavior

System.Net.Http.HttpClientHandler is NOT found

Regression?

Yes. Works with .NET 6 and below

Known Workarounds

Use ignoreCase as false, but might cause side effects

Configuration

.NET SDK (reflecting any global.json): Version: 7.0.100-preview.1.22107.7 Commit: fa575c5753

Runtime Environment: OS Name: Windows OS Version: 10.0.22000 OS Platform: Windows RID: win10-x64 Base Path: <>\AppData\Local\Microsoft\dotnet\sdk\7.0.100-preview.1.22107.7\

Host (useful for support): Version: 7.0.0-preview.1.22076.8 Commit: 405337939c

Other information

No response

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 17 (13 by maintainers)

Commits related to this issue

Most upvoted comments

It looks like we’ve found the problem, and Jan has a fix at https://github.com/dotnet/runtime/pull/65157

I don’t think this is infrastructure related. I just doubled checked the System.Net.Http assembly and compared the .NET 7 P1 vs the .NET 6 one and their metadata is identical (except for assembly versions).

As a note, I tried this on Windows 11 and macOS and it reproed on both OSs. Something interesting that I found that also tells me it has nothing to do with the assembly, is that if I change the type to search for to be System.Net.Http.ByteArrayContent for example, it doesn’t fail:

dotnet run
Type found with assembly.GetType(typeName, throwOnError: false, ignoreCase: true): System.Net.Http.ByteArrayContent
Type found with assembly.GetType(typeName, throwOnError: false, ignoreCase: false): System.Net.Http.ByteArrayContent
dotnet run
Type found with assembly.GetType(typeName, throwOnError: false, ignoreCase: true): System.Net.Http.HttpClient
Type found with assembly.GetType(typeName, throwOnError: false, ignoreCase: false): System.Net.Http.HttpClient
 dotnet run
Type found with assembly.GetType(typeName, throwOnError: false, ignoreCase: true): System.Net.Http.HttpContent
Type found with assembly.GetType(typeName, throwOnError: false, ignoreCase: false): System.Net.Http.HttpContent

So it seems like maybe something changed in our string comparisons and it is hitting a bug where ignore case for the specific HttpClientHandler string is not being compared correctly with ignore case.

Adding @tarekgh as he might have some ideas. Also adding @ericstj as this is blocking the p1 release.