Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MissingMethodException: Method not found: System.Net.Http.WinHttpHandler.set_ServerCertificateValidationCallback #28826

Closed
gaborposz opened this issue Feb 28, 2019 · 11 comments

Comments

@gaborposz
Copy link

I'm using the System.Net.Http.WinHttpHandler 4.5.2 NuGet package from a .NET Framework 4.7 project, and I get the following exception when I use the ServerCertificateValidationCallback property:
System.MissingMethodException: 'Method not found: 'Void System.Net.Http.WinHttpHandler.set_ServerCertificateValidationCallback(System.Func'5<System.Net.Http.HttpRequestMessage,System.Security.Cryptography.X509Certificates.X509Certificate2,System.Security.Cryptography.X509Certificates.X509Chain,System.Net.Security.SslPolicyErrors,Boolean>)'.'

The rest of the package is working well, but due to this error I cannot handle missing or non-trusted certificate errors.

Eventually I was able to create a pretty simple Visual Studio Solution to reproduce the problem:
WinHttpHandlerPropertyCheck.zip

I have two projects in it:

  • A library, referencing the System.Net.Http.WinHttpHandler NuGet package (with PackageReference).
  • And an executable, referencing the System.Net.Http assembly (from the .NET Framework). This executable is also referencing and using the library.

When the executable calls the library, the MissingMethodException is thrown.

I've already learned the following:
The executable links with the 4.0.0 System.Net.Http assembly that is available in GAC (since it is coming from the .NET Framework), while the library links with the 4.2.0 System.Net.Http assembly (because
the WinHttpHandler package is explicitly referencing that version). Both dlls are loaded into the running executable, but when the CLR tries to JIT the library's method the parameter types in the ServerCertificateValidationCallback mismatch with the already loaded types, and the exception is thrown.

Any idea how to solve it?
My library is supposed to be used by various executables, so application specific solutions (e.g. app.config changes) are not working for me.

Thank you in advance,
Gabor

@davidsh
Copy link
Contributor

davidsh commented Feb 28, 2019

The executable links with the 4.0.0 System.Net.Http assembly that is available in GAC (since it is coming from the .NET Framework), while the library links with the 4.2.0 System.Net.Http assembly (because the WinHttpHandler package is explicitly referencing that version).

That is causing the mismatch since the 4.0.0 System.Net.Http.dll assembly from . NET Framework doesn't have the required property.

@ericstj can you advise on this? Is this a packaging problem?

cc: @karelz

@gaborposz
Copy link
Author

Hi,
Some additional info:

The 4.2.0 System.Net.Http.dll is copied during build from the following path:
C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Net.Http.dll

If I overwrite it here with the 4.0.0 System.Net.Http.dll from GAC, then everything works fine.

It seems System.Net.Http.WinHttpHandler only needs the 4.0.0 version, so it's really strange that the NuGet PackageReference brings the 4.2.0 into the bin folder...

Another workaround is an assembly redirect in the executable's app.config:

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

But as I mentioned in my original post: unfortunately it does not help in my case :(

Regards,
Gabor

@davidsh
Copy link
Contributor

davidsh commented Apr 1, 2019

This is basically a duplicate of #24382.

@davidsh
Copy link
Contributor

davidsh commented Apr 1, 2019

But as I mentioned in my original post: unfortunately it does not help in my case :(

Most of the workaround suggested do involve using assembly binding redirects in the app.config file. That won't help you as the library author. It would be a step required by consumers of your library that build executables.

One thing not mentioned in this issue is the version of Visual Studio being used. The most recent updates to Visual Studio 2017 include some logic in the tools that try to smooth out the problems here and automatically generate the binding redirects to prefer using the inbox (GAC'd) version of System.Net.Http.

Have you tried using the latest Visual Studio 2017 updates?

@gaborposz
Copy link
Author

I've installed the latest Visual Studio update (15.9.10), cleaned the output directories, rebuilt the solution, but it's the same, the MethodNotFoundException is still thrown :(

@karelz
Copy link
Member

karelz commented Apr 2, 2019

Can you please share with us exact steps how to reproduce the problem? (ideally on minimal repro)

@davidsh
Copy link
Contributor

davidsh commented Apr 2, 2019

I downloaded the link you posted: WinHttpHandlerPropertyCheck.zip

I did not get the exception.

I see this in the Output pane of Visual Studio 2017:

'WinHttpHandlerPropertyCheck.exe' (CLR v4.0.30319: DefaultDomain): Loaded 'C:\WINDOWS\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll'. Symbols loaded.
'WinHttpHandlerPropertyCheck.exe' (CLR v4.0.30319: DefaultDomain): Loaded 'C:\Users\dshulman\Downloads\WinHttpHandlerPropertyCheck\WinHttpHandlerPropertyCheck\bin\Debug\WinHttpHandlerPropertyCheck.exe'. Symbols loaded.
'WinHttpHandlerPropertyCheck.exe' (CLR v4.0.30319: WinHttpHandlerPropertyCheck.exe): Loaded 'C:\Users\dshulman\Downloads\WinHttpHandlerPropertyCheck\WinHttpHandlerPropertyCheck\bin\Debug\WinHttpHandlerUser.dll'. Symbols loaded.
'WinHttpHandlerPropertyCheck.exe' (CLR v4.0.30319: WinHttpHandlerPropertyCheck.exe): Loaded 'C:\Users\dshulman\Downloads\WinHttpHandlerPropertyCheck\WinHttpHandlerPropertyCheck\bin\Debug\System.Net.Http.WinHttpHandler.dll'. Symbols loaded.
'WinHttpHandlerPropertyCheck.exe' (CLR v4.0.30319: WinHttpHandlerPropertyCheck.exe): Loaded 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Net.Http\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Net.Http.dll'. Symbols loaded.
'WinHttpHandlerPropertyCheck.exe' (CLR v4.0.30319: WinHttpHandlerPropertyCheck.exe): Loaded 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0__b77a5c561934e089\System.dll'. Symbols loaded.
'WinHttpHandlerPropertyCheck.exe' (CLR v4.0.30319: WinHttpHandlerPropertyCheck.exe): Loaded 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Core\v4.0_4.0.0.0__b77a5c561934e089\System.Core.dll'. Symbols loaded.
'WinHttpHandlerPropertyCheck.exe' (CLR v4.0.30319: WinHttpHandlerPropertyCheck.exe): Loaded 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Configuration\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Configuration.dll'. Symbols loaded.
'WinHttpHandlerPropertyCheck.exe' (CLR v4.0.30319: WinHttpHandlerPropertyCheck.exe): Loaded 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Xml\v4.0_4.0.0.0__b77a5c561934e089\System.Xml.dll'. Symbols loaded.
The program '[0x51C0] WinHttpHandlerPropertyCheck.exe' has exited with code 0 (0x0).
The program '[0x51C0] WinHttpHandlerPropertyCheck.exe: Program Trace' has exited with code 0 (0x0).

@karelz
Copy link
Member

karelz commented Apr 2, 2019

@gaborposz are you able to reproduce the problem on clean VM?
Let's try to separate product problems from machine-setup / misconfiguration / dirty machine problems.

@davidsh
Copy link
Contributor

davidsh commented Apr 2, 2019

One thing I noticed when building the solution:

1>------ Rebuild All started: Project: WinHttpHandlerUser, Configuration: Debug Any CPU ------
1>  WinHttpHandlerUser -> C:\Users\dshulman\Downloads\WinHttpHandlerPropertyCheck\WinHttpHandlerPropertyCheck\bin\Debug\WinHttpHandlerUser.dll
2>------ Rebuild All started: Project: WinHttpHandlerPropertyCheck, Configuration: Debug Any CPU ------
2>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\Microsoft.Common.CurrentVersion.targets(2110,5): warning MSB3277: Found conflicts between different versions of "System.Net.Http" that could not be resolved.  These reference conflicts are listed in the build log when log verbosity is set to detailed.
2>  WinHttpHandlerPropertyCheck -> C:\Users\dshulman\Downloads\WinHttpHandlerPropertyCheck\WinHttpHandlerPropertyCheck\bin\Debug\WinHttpHandlerPropertyCheck.exe
========== Rebuild All: 2 succeeded, 0 failed, 0 skipped ==========

This message

"C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\Microsoft.Common.CurrentVersion.targets(2110,5): warning MSB3277: Found conflicts between different versions of "System.Net.Http" that could not be resolved. These reference conflicts are listed in the build log when log verbosity is set to detailed." is shown.

But when I run the application, it is able to load the GAC'd version of System.Net.Http (as you can see from the output I posted in the earlier comment).

I noticed that both of your projects in the solution target .NET Framework 4.7. On my machine, though, I have .NET Framework 4.7.2 actually installed. What version of .NET Framework do you have installed on your machine?

Can you run the following C# program and give me the output? It will tell us the specific binaries you are using on your machine.

using System;
using System.IO;
using System.Diagnostics;
using System.Net.Http;
using System.Reflection;

public class App
{
    public static void Main(string[] args)
    {
        Console.WriteLine(GetAssemblyVersion(typeof(Uri))); // System.dll
        Console.WriteLine();
        Console.WriteLine(GetAssemblyVersion(typeof(HttpClient))); // System.Net.Http.dll
    }

    public static string GetAssemblyVersion(Type t)
    {
        string path = t.Assembly.Location;
        FileVersionInfo fi = FileVersionInfo.GetVersionInfo(path);

        string retval = "*************************************************************\r\n";
        retval += "Information for: " + Path.GetFileName(path);

        retval += "\r\n  Location:        " + Path.GetDirectoryName(path);
        retval += "\r\n  CLR Version:     " + t.Assembly.ImageRuntimeVersion;
        retval += "\r\n  File Version:    " + fi.FileVersion;
        retval += "\r\n  Creation Date:   " + System.IO.File.GetCreationTime(path);
        retval += "\r\n  Last Modified:   " + System.IO.File.GetLastWriteTime(path);
        retval += "\r\n*************************************************************";
        return retval;
    }
}

@gaborposz
Copy link
Author

Hello,
The .NET Framework 4.7.2 install magically solved the problem. (Previously I had only 4.7.1 installed on my machine.)

This was the System.Net.Http.dll's version in the GAC before the install:

*************************************************************
Information for: System.Net.Http.dll
  Location:        C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Net.Http\v4.0_4.0.0.0__b03f5f7f11d50a3a
  CLR Version:     v4.0.30319
  File Version:    4.7.2661.0 built by: NET471REL1LAST_C
  Creation Date:   6/26/2018 8:25:50 AM
  Last Modified:   5/11/2018 8:12:31 PM
*************************************************************

And after the install:

*************************************************************
Information for: System.Net.Http.dll
  Location:        C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Net.Http\v4.0_4.0.0.0__b03f5f7f11d50a3a
  CLR Version:     v4.0.30319
  File Version:    4.7.3062.0 built by: NET472REL1
  Creation Date:   4/3/2019 9:51:53 AM
  Last Modified:   4/3/2019 9:51:53 AM
*************************************************************

As you can see, the File Version is different.
I believe it works with .NET Framework 4.7.2 because it installs a newer System.Net.Http.dll to the GAC, that is already compatible with the System.Net.Http.WinHttpHandler package.

I've uploaded the collected logs (before and after) to here:
MethodNotFoundException_Logs.zip

Maybe in the System.Net.Http.WinHttpHandler NuGet package you could correct the .nuspec to use a different System.Net.Http.dll version in case of .NET Framework prior to 4.7.2. But I'm not sure if it is possible...

Anyway, .NET Framework 4.7.2 seems to be a possible workaround for us, so thanks a lot for the help!

Regards,
Gabor

@karelz
Copy link
Member

karelz commented Apr 3, 2019

Closing the issue as addressed with 4.7.2.
While it is somewhat suspicious, I would wait for more people to hit it before we dig too deep (these kind of investigations are usually fairly costly).
Let me know if you disagree ...

@karelz karelz closed this as completed Apr 3, 2019
@msftgits msftgits transferred this issue from dotnet/corefx Feb 1, 2020
@msftgits msftgits added this to the 3.0 milestone Feb 1, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 14, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants