IdentityModel is a library that uses HttpClient internally – it should also run on all recent versions of the .NET Framework and .NET Core.
HttpClient is sometimes “built-in”, e.g. in the .NET Framework, and sometimes not, e.g. in .NET Core 1.x. So fundamentally there is a “GAC version” and a “Nuget version” of the same type.
We had lots of issues with this because it seemed regardless in which combination you are using the flavours of HttpClient, this will lead to a problem one way or another (github issues). The additional confusion was added by the fact that the .NET tooling had certain bugs in the past that needed workarounds that lead to other problems when those bugs were fixes in later tooling.
Long story short – every time I had to change the csproj file, it broke someone. The latest issue was related to Powershell and .NET 4.7.x (see here).
I once and for all wanted an official statement, how to deal with HttpClient – so I reached out to Immo (@terrajobst) over various channels. Turns out I was not alone with this problem.
Despite him being on holidays during that time, he gave a really elaborate answer that contains both excellent background information and guidance.
I thought I should copy it here, so it becomes more search engine friendly and hopefully helps out other people that are in the same situation (original thread here).
“Alright, let me try to answer your question. It will probably have more detail than you need/asked for but I might be helpful to start with intention/goals and then the status quo. HttpClient started out as a NuGet package (out-of-band) and was added to the .NET Framework in 4.5 as well (in-box).
With .NET Core/.NET Standard we originally tried to model the .NET platform as a set of packages where being in-box vs. out-of-band no longer mattered. However, this was messier and more complicated than we anticipated.
As a result, we largely abandoned the idea of modeling the .NET platform as a NuGet graph with Core/Standard 2.0.
With .NET Core 2.0 and .NET Standard 2.0 you shouldn’t need to reference the SystemNetHttpClient NuGet package at all. It might get pulled from 1.x dependencies though.
Same goes for .NET Framework: if you target 4.5 and up, you should generally use the in-box version instead of the NuGet package. Again, you might end up pulling it in for .NET Standard 1.x and PCL dependencies, but code written directly against .NET Framework shouldn’t use it.
So why does the package still exist/why do we still update it? Simply because we want to make existing code work that took a dependency on it. However, as you discovered that isn’t smooth sailing on .NET Framework.
The intended model for the legacy package is: if you consume the package from .NET Framework 4.5+, .NET Core 2+, .NET Standard 2+ the package only forwards to the platform provided implementation as opposed to bring it’s own version.
That’s not what actually happens in all cases though: the HTTP Client package will (partially) replace in-box components on .NET Framework which happen to work for some customers and fails for others. Thus, we cannot easily fix the issue now.
On top of that we have the usual binding issues with the .NET Framework so this only really works well if you add binding redirects. Yay!
So, as a library author my recommendation is to avoid taking a dependency on this package and prefer the in-box versions in .NET Framework 4.5, .NET Core 2.0 and .NET Standard 2.0.
what a mess this is…. i think i am running into some version of this right now.
i have code that runs on windows 10 but fails on windows server 2016
it fails in identitymodel 3.8 on trying to call the userinfo async extension with a missing method error.
i copied the same dll files between client and server to try and make the same environment.
but so far no joy.