Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

System.Net.Http MethodNotFoundException when executing method on .NET Framework 4.7.1 library loaded through Reflection

Setup

As part of migrating a large VS solution from .Net 4.6 to 4.7.1, I have replaced all packages.config files with "PackageReferences" in each .csproj file and removed the corresponding standard "Reference" tags containing hint paths pointing at the now obsolete "../packages/*" directory. I have also added the <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> and <RestoreProjectStyle>PackageReference</RestoreProjectStyle> to each .csproj file. This .Net 4.7.1 library has various project references to other .Net 4.7.1 libraries and NuGet packages (some of them targeting .NET Standard versions).

Execution

I have a PowerShell script which loads this particular .NET 4.7.1 library through Assembly.LoadFrom("C:\Net471LibraryOutput\Net471Library.dll"), instantiates a class in that assembly through new-object Net471Library.MyClass, and then attempts to execute an async method on that class, but is met with a "MethodNotFoundExcepion" saying that a method defined in a PackageReferenced NugetPackage which references System.Net.Http can't be found.

Observations

My .NET 4.7.1 library references another 4.7.1 project which references System.Net.Http without a specific version, which VS 2017 resolves to version 4.2.0.0 which it found at C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net471\lib\System.Net.Http.dll When I look at the current AppDomain's assemblies after loading this library through reflection, but before executing the command I see my 4.7.1 library's .dll and no System.Net.Http.dll has been loaded. After executing the command I find 2 entries for System.Net.Http have been loaded into the appdomain, each with a distinct version.

  • C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Net.Http\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Net.Http.dll (version 4.0.0.0)
  • C:\Net471LibraryOutput\System.Net.Http.dll (version 4.2.0.0)

If I hide System.Net.Http 4.2.0.0 from VS and rebuild, Net471Library output no longer contains System.Net.Http.dll, and if I repeat those steps without that .dll present, the method executes successfully (no "MethodNotFoundException" on the referenced NuGet package method). If I allow VS to find System.Net.Http 4.2.0.0, even if I set all referenced projects to use 4.0.0.0 specifically (though I can't adjust the PackageReferenced NuGet packages), version 4.2.0.0 still gets placed in the output and I receive the same error. If I try to add a reference to System.Net.Http directly to the library to try to force the output, I get build error CS0433 "The type 'HttpResponseMessage' exists in both 'System.Net.Http, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' and 'System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'"

I have made several attempts to reproduce the issue in a simplified solution with fewer dependencies to narrow down the issue but have been unsuccessful so far.

like image 870
Nathan Turnbow Avatar asked Jul 01 '26 07:07

Nathan Turnbow


1 Answers

The reason why you are seeing this is that most likely you are using Visual Studio 15.5.* to build your app, which is missing a recent fix we added for projects targetting 4.7.1 in order to automatically add binding redirects to a few list of facades. That change has been added now and will be shipped in VS 15.6 Preview 3 and later versions. In order to workaround the issue for now, is to manually add the binding redirects you need which in this case is:

<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
  <dependentAssembly>
    <assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.2.0.0" />
  </dependentAssembly>
</assemblyBinding>

Can you check if adding that fixes your issue? If you want more info on the fix we made, you can take a look at this github pull request: https://github.com/dotnet/corefx/pull/25786

like image 66
Jose Perez Rodriguez Avatar answered Jul 04 '26 13:07

Jose Perez Rodriguez