# System.Net.Http v4.2.0.0 being copied/loaded from MSBuild tooling #25773

Closed
opened this issue Dec 7, 2017 · 97 comments

Projects
None yet

### camp-007 commented Dec 7, 2017

 This issue was mentioned in the following comment, but that thread seemed to deal primarily with a different scenario. @karelz requested a separate issue be filed and it doesn't seem that happened. #22781 (comment) The issue seems to be that when adding a reference to certain nuget packages, the version of System.Net.Http in the bin directory gets copied from C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Net.Http.dll which is a later version than what is available on nuget. Here is the simplest repro I could come up with: Using VS Enterprise 15.5, create a new console app 'ConsoleApp1' that targets .net 4.6.1 Create a new class library 'ClassLibrary1' that targets .net 4.6.1 ConsoleApp1 references ClassLibrary1 Add nuget package System.Net.Http v4.3.3 to ConsoleApp1 Add nuget package System.Net.Http v4.3.3 to ClassLibrary1 ClassLibrary1.Class1 needs to instantiate HttpClient and ConsoleApp1.Program needs to instantiate HttpClient and ClassLibrary1.Class1 At this point everything builds/runs fine. a. Version of System.Net.Http in both bin directories is v4.1.1.2 dated 9/5/2017. b. If you look at the System.Net.Http reference in the VS properties window of solution explorer, it will show the version as 4.1.1.2. c. In the properties window ClassLibrary1 shows the path {solution_dir}\packages\System.Net.Http.4.3.3\lib\net46\System.Net.Http.dll Add nuget package System.Collections.Immutable v1.4.0 to ClassLibrary1 At this point there are problems a. Building will generate the warning "Found conflicts between different versions of 'System.Net.Http' that could not be resolved" b. Running the app will generate a run-time exception: "Unhandled Exception: System.IO.FileLoadException: Could not load file or assembly 'System.Net.Http, Version=4.2.0.0" c. Version of System.Net.Http in the ClassLibrary1 bin directory is v4.2.0.0 and dated 12/4/2017 d. The reference properties window in VS for ClassLibrary1 shows the path as C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Net.Http.dll In short, for some reason after adding nuget package for System.Collections.Immutable v1.4.0, the MSBuild version of System.Net.Http seems to get introduced into the project and causes problems. I don't know if System.Collections.Immutable is unique in triggering this scenario. The previous issue/comment suggests that other packages might also trigger this (System.Threading.Tasks.Dataflow) I can work around this issue with the following binding redirect:   But it seems incorrect to have to redirect backwards like that.
Author

### camp-007 commented Dec 7, 2017

 My apologies, it seems the author of the previous comment I referenced did in fact open an issue here: #23306 However, I'm trying to read that chain and understand the final outcome. It isn't clear to me what I'm doing wrong in my fairly basic scenario. It seems very confusing/wrong that I'm getting System.Net.Http v4.2.0.0 introduced into my build. At the very least, I guess I'm still unclear on the simplest path to resolve the issue.
Member

### davidsh commented Dec 7, 2017

 But it seems incorrect to have to redirect backwards like that. Doing that kind of binding redirect is the correct workaround to this problem. However, you should just bind back to the 4.0.0..0 version. Doing so will ensure you use the GAC'd version of System.Net.Http.dll from the .NET Framework and not use the System.Net.Http.dll binary from the NuGet package. I.e.   Although, reading your repro steps above, I don't understand why you would explicitly do these steps: Add nuget package System.Net.Http v4.3.3 to ConsoleApp1 Add nuget package System.Net.Http v4.3.3 to ClassLibrary1 If you're building a .NET Framework 4.6.x app, you should just use standard references to System.Net.Http and not bring in any Nuget package for System.Net.Http.

Member

### davidsh commented Dec 7, 2017

 cc: @karelz @terrajobst - more packaging issues related to bindings.
Author

### camp-007 commented Dec 7, 2017

 Thanks for the feedback! This may be the key concept I'm struggling with: If you're building a .NET Framework 4.6.x app, you should just use standard references to System.Net.Http and not bring in any Nuget package for System.Net.Http. Honestly, when targeting .NET Framework, I'm often confused why I usually end up with nuget package references targeting System.* (something I know should be in the framework). But this happens to me all the time. When building an app targeting 4.6.X a reference to the GAC'd version of System.Net.Http is included by default and I wouldn't think I need to add the nuget package for System.Net.Http. However, the real scenario where I encountered this problem results from my top level app ultimately referencing some other nuget packages that have a dependency on System.Net.Http from nuget (IdentityModel was the particular package introducing it for me). Thus, my project will end up with nuget package references to System.Net.Http regardless. In my simple repro, I agree it wouldn't be something I'd need to do. In my experience, apps targeting .NET 4.6.x often end up with a nuget package dependency on System.Net.Http because of other packages. Is this a mistake/flaw in 3rd party packages for them to have a dependency on System.Net.Http package for .net 4.6.x? Or is there a valid reason why they need that? It is a generalization, but it feel like I run into System.Net.Http package issues a LOT. I think what you are saying is that the general rule of thumb should be: If your top level app is targeting .NET 4.6.x you will want to redirect any references to System.Net.Http (even higher versions!!) to 4.0.0.0 since that is what should be in the framework GAC. Am I understanding that correctly? Note that my project has true so as a developer I'm hoping/praying to never have to make manual decisions about my binding redirects (because most of us find them very annoying to have to try and think about and manage). What is odd, is that if I don't have any redirects in my app.config, none are generated at compile time. However, if I add the redirect you mentioned (to v4.0.0.0) the config file generated at compile time actually is changed to redirect to 4.1.1.2. That doesn't really matter, I'm just noting that all this feels very confusing and not very intuitive to simple minded folk like me. I very much appreciate your feedback and guidance!
Author

### camp-007 commented Dec 7, 2017

 Also, Can you confirm that getting v4.2.0.0 referenced from C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Net.Http.dll would be expected/desirable?
Member

### davidsh commented Dec 7, 2017

 If your top level app is targeting .NET 4.6.x you will want to redirect any references to System.Net.Http (even higher versions!!) to 4.0.0.0 since that is what should be in the framework GAC. Am I understanding that correctly? So, it's actually even more complicated unfortunately. In the old days, there were just references to .NET Framework assemblies. Then came NuGet packages which added some complexity. Recently with NETStandard20, developers can build class library that target NETStandard20 and use those on .NET Framework and/or .NET Core. System.Net.Http is available in a NuGet package because we made a decision early in .NET Core development to add new APIs to System.Net.Http. But because those APIs at the time were not in .NET Framework 4.6.x, we created a new "out-of-band" (OOB) package that contained the revised implementation and thus could carry the updated API for developers that wanted it. We later discovered that creating new System.Net.Http binaries outside of the .NET Framework had issues such as what you are discovering. So, we have revised that approach. We added those new APIs directly to .NET Framework 4.7.1 as part of the NETStandard20 reconcillation effort. And we have been improving tooling to help reconcile some of these version conflicts. In my experience, apps targeting .NET 4.6.x often end up with a nuget package dependency on System.Net.Http because of other packages. Is this a mistake/flaw in 3rd party packages for them to have a dependency on System.Net.Http package for .net 4.6.x? Or is there a valid reason why they need that? It is a generalization, but it feel like I run into System.Net.Http package issues a LOT. Yes, most problems that developers are seeing with System.Net.Http assembly version mismatches is that they aren't explicitly pulling in the NuGet System.Net.Http but rather implicitly thru other package references. Getting this problem smoothed out for developers relies on getting the binding redirects fixed up. Visual Studio 2017 has made some additional tooling changes in the latest updates (15.5 for example) to help with this and make sure that the binding redirects resolve back to the inbox System.Net.Http.dll binary. There have also been improvements to .NET Framework 4.7 and 4.7.1 and beyond to help resolve these mismatches better.
Member

### davidsh commented Dec 7, 2017

 Also, Can you confirm that getting v4.2.0.0 referenced from C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Net.Http.dll would be expected/desirable? I can't really comment on that because I don't have your complete Visual Studio solution. So, I can't trace thru all the possible references you have. But as long as you have a buildable solution now with binding redirects that work for you, then you should be good.
Author

### camp-007 commented Dec 7, 2017

 HttpIssue.zip Here is my repro solution. Something still feels very fishy about that 4.2.0.0 version getting brought in.

### danielcrabtree commented Dec 8, 2017

 I ran into the same problem, one of many with System.Net.Http. But I ran into the problem when upgrading from .NET Framework 4.7 to .NET Framework 4.7.1. The problem seems to be that the libraries in: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net471\lib\ Conflict with the libraries in: C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.1\ Deleting the MSBuild version of the libraries enabled me to resolve the issue. It is perhaps worth noting that the MSBuild net47 library folder contains very few libraries and does not include System.Net.Http, but net471 and net461 do. net462 does not, so I suspect like net47 there would be no problems there. As an alternative solution, I was also able to get things working by manually adding the right binding redirects. But for several reasons, feel that deleting the MSBuild version of the libraries is the better solution. I also tried AutoGenerateBindingRedirects and GenerateBindingRedirectsOutputType, but couldn't get those to work properly. Interestingly, I didn't get any of the expected compile time warnings about different library versions until I had deleted the MSBuild libraries.

### natelaff commented Dec 11, 2017 • edited

 Well, I had all of this working. My project is targeting .NET Framework 4.7.1, and references a .NET Standard 2.0 library. Everything was happy until I upgraded from VS 15.4 to 15.5, now that redirect doesn't even work and I have to copy System.Net.Http.dll into the install location to get this rolling.

### ma-bjo commented Dec 14, 2017 • edited

 I have been struggling with this issue as well. After installing VS 15.5, re-targeting the projects to .NET Framework 4.7.1 and changing to PackageReference instead of packages.config for nuget I get the 4.2.0.0 version of System.Net.Http.dll copied to the output folder. In my case the dependency on the System.Net.Http nuget package comes from using the newer System.Threading.Tasks.Dataflow from nuget. Turning on detailed logging gives me this: Using "ResolvePackageFileConflicts" task from assembly "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\\tools\net46\Microsoft.NET.Build.Extensions.Tasks.dll". and then Encountered conflict between 'Reference:C:\Users\myuser\.nuget\packages\system.net.http\4.1.0\ref\net46\System.Net.Http.dll' and 'Reference:System.Net.Http'. Choosing 'Reference:System.Net.Http' because AssemblyVersion '4.2.0.0' is greater than '4.1.0.0'. To me this behavior seems intentional, but I have yet to find some information online to support it. The automatically generated binding redirects are also consistent, redirecting 0.0.0.0 - 4.2.0.0 to 4.2.0.0. The only place where I still have to do manual redirects are for web applications. This is however not in line with what @davidsh wrote earlier - this assembly must be deployed for things to work, and it will be used instead of the assembly already present in .NET Framework 4.7.1. Can someone please confirm that ending up with 4.2.0.0 in this scenario is intended? (Btw, the title of this issue says v4.3.0.0, but I'm pretty sure that is incorrect and should be changed to v4.2.0.0. Debugging build problems in this scenario gets extremely difficult, since there is no correlation between the nuget package version, the assembly version or the file version.)

Author

### camp-007 commented Dec 15, 2017

 Sorry you are correct the title had a typo and v4.2.0.0 is what is getting copied into the bin directory

### stijnherreman commented Dec 18, 2017 • edited

 I've just upgraded an entire solution to 4.7.1 and I'm still seeing conflicts, but I don't know what exactly causes it. Project A chooses C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net471\lib\System.Net.Http.dll and detects it as version 4.2.0.0 Project B, which depends on project A, chooses C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.1\System.Net.Http.dll and detects it as version 4.0.0.0 First I thought 4.2.0.0 is only chosen when the project depends on a netstandard NuGet package, but it doesn't seem to make a difference. Below is the relevant build output: 13>------ Build started: Project: A, Configuration: Debug Any CPU ------ 13> Encountered conflict between 'Reference:System.Net.Http' and 'Platform:System.Net.Http.dll'. Choosing 'Reference:System.Net.Http' because AssemblyVersion '4.2.0.0' is greater than '4.0.0.0'. 13> Encountered conflict between 'Platform:System.Net.Http.dll' and 'CopyLocal:C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net471\lib\System.Net.Http.dll'. Choosing 'CopyLocal:C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net471\lib\System.Net.Http.dll' because AssemblyVersion '4.2.0.0' is greater than '4.0.0.0'. 16>------ Build started: Project: B, Configuration: Debug Any CPU ------ 16> There was a conflict between "System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" and "System.Net.Http, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a". 16> "System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" was chosen because it was primary and "System.Net.Http, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" was not. 16> References which depend on "System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" [C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.1\System.Net.Http.dll]. 16> C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.1\System.Net.Http.dll 16> Project file item includes which caused reference "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.1\System.Net.Http.dll". 16> System.Net.Http 16> References which depend on "System.Net.Http, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" [C:\redacted\A\bin\Debug\System.Net.Http.dll]. 16> C:\redacted\A\bin\Debug\X.dll 16> Project file item includes which caused reference "C:\redacted\A\bin\Debug\X.dll". 16> C:\redacted\A\bin\Debug\A.dll 16> C:\redacted\A\bin\Debug\Y.dll 16> Project file item includes which caused reference "C:\redacted\A\bin\Debug\Y.dll". 16> C:\redacted\A\bin\Debug\A.dll 16> C:\redacted\A\bin\Debug\Z.dll 16> Project file item includes which caused reference "C:\redacted\A\bin\Debug\Z.dll". 16> C:\redacted\A\bin\Debug\A.dll 16> C:\redacted\A\bin\Debug\A.dll 16> Project file item includes which caused reference "C:\redacted\A\bin\Debug\A.dll". 16> C:\redacted\A\bin\Debug\A.dll  @karelz is this issue on your radar?

### stijnherreman commented Dec 19, 2017 • edited

 Doing that kind of binding redirect is the correct workaround to this problem. However, you should just bind back to the 4.0.0..0 version. Doing so will ensure you use the GAC'd version of System.Net.Http.dll from the .NET Framework and not use the System.Net.Http.dll binary from the NuGet package. @davidsh I know OP is using net461, but I thought the binding redirects wouldn't be needed anymore with the combination of net471 and VS 15.5? Will .NET Framework 4.x need the binding redirects to 4.0.0.0 forever? Or is it only needed when a project does not reference one of Microsoft's packages that have the 4.2.0.0 version?

### danielcrabtree commented Dec 19, 2017

 The problem seems to be the existence of the MSBuild libraries, I think they are the wrong version, as surely they should match the Reference Assembly version. I was able to get all projects using the Reference Assemblies instead of the MSBuild libraries (without changing the actual dependencies), but after a while, it would revert to the MSBuild libraries. I was able to resolve the issue using binding redirects, but could not get AutoGenerateBindingRedirects to work. I abandoned this approach and simply deleted (moved) the MSBuild libraries, because the errors would happen at runtime (no errors at compile time) and I wasn't sure I had all the necessary binding redirects.

### natelaff commented Dec 19, 2017

 @stijnherreman Well, it did work gloriously in net471 + netstardard20 for the few weeks that 15.3 was out. 15.4 turned around and broke it again :P

### ma-bjo commented Dec 22, 2017

 I have finally managed to get our solution to build without getting any System.Net.Http.dll assemblies copied to the output folder, with no redirects and no removal of dlls from the build environment. I thought I should share some information about my findings if it helps investigating similar issues. As I mentioned earlier, we target .NET Framework 4.7.1 and use PackageReference to bring in the nuget packages. The problems for us started when we referenced the System.Threading.Tasks.Dataflow nuget package, v4.8.0. I have now found that moving back to v.4.7.0 of that package solves the problem. If we do that we no longer get any System.Net.Http.dll copied to the output folder and get to use the one already available as part of the framework. So what is different? I have a hunch that this is because the package dependencies are specified differently for these two versions. For v4.7.0, the nuget package specifically states ".NETFramework, Version=v4.5 No dependencies". But for v4.8.0, there is no longer anything explicitly stated for .NETFramework, only for .NETCoreApp, .NETStandard, .NETPortable and Xamarin of various versions. For example, it mentions ".NETStandard, Version=v2.0 No dependencies". Could it be that NuGet 4.3 and/or MSBuild 15.5 is failing to understand that .NETFramework completely fulfills .NETStandard 2.0? We also saw similar issues with the NUnit package version we used, v3.6.1. That package only lists dependencies for ".NETStardard, Version=v1.6", and using that causes (a different!) version of System.Net.Http.dll to appear in the output folder. Moving to v3.7.1, where ".NETFramework,Version=v4.5 No dependencies" is stated, System.Net.Http is correctly picked up from the framework and not copied to the output folder. So the problem seems to be nuget packages that does not specifically state their dependencies for .NET Framework.

Closed

Member

### davidsh commented Jan 2, 2018

 @davidsh I know OP is using net461, but I thought the binding redirects wouldn't be needed anymore with the combination of net471 and VS 15.5? Will .NET Framework 4.x need the binding redirects to 4.0.0.0 forever? Or is it only needed when a project does not reference one of Microsoft's packages that have the 4.2.0.0 version? @weshaggard needs to answer this question. He is the subject matter expert on this topic.
Member

### weshaggard commented Jan 2, 2018

 @AlexGhiondea @joperezr there seems to be a number of issues related to the tooling and support package throughout this thread. Can you please make sure that your current tooling fixes handle these cases?

### tomek14 commented Jan 11, 2018

 I hit the same issue. Full NET 4.7.1 project references netstandard2. I thought net471 fully supports netstandard2...

### ma-bjo commented Jan 12, 2018

 Got the same issue again with another package. We used System.Buffers 4.4.0 in order to use ArrayPool, and that caused a strange 4.2.0.0 version of System.Diagnostics.Tracing.dll being copied to the output folder. Once again the workaround was to move back to 4.3.0 that states ".NETFramework,Version=v4.5 No dependencies", which version 4.4.0 does not do. So once again the problem seems to be nuget packages that does not specifically state their dependencies for .NET Framework.

Closed

### onyxmaster commented Jan 15, 2018

 Setting property False for 4.7.1 projects helps. This might break unknown other things though.

### stijnherreman commented Jan 15, 2018 • edited

 @onyxmaster Huh, if I understand microsoft/msbuild#2199 (should be part of 15.5 release) correctly, a similar property ImplicitlyExpandDesignTimeFacades was set to True in order to make net471 work correctly with netstandard2.0 So that property fixed one issue but introduced another?

### wuwei26 commented Oct 2, 2018

 Why is the Visual Studio 2017 Build Tools for 4.7.1 version of the dll different from the nuget version of the file for 4.7.1? Visual Studio is 4.6.26011.1 while the nuget version is 4.6.25705.01; at the very least you would think you could keep the VS and nuget versions the same...
Member

### karelz commented Oct 2, 2018

 VS is different product than System.Net.Http nuget library (.NET tooling / IDE vs. .NET platform component, shipping from GitHub)
Member

### joperezr commented Oct 2, 2018

 @Jehoel what your issue tells me is that the server where your app is running doesn't have 4.7.2 installed. It may run fine on your machine because you do have 4.7.2 but the server must be on an earlier version of .NET. For regular console apps, we specify on the AppConfig the version of .NET that you target and when trying to load your app we ensure that this version is installed on the machine or we fail to load it, but Web Apps behave differently.

### Jehoel commented Oct 2, 2018 • edited

 @joperezr I'll admit that was my problem: I was deploying to Azure App Services which doesn't yet support 4.7.2, only 4.7.1 (progress in here: Azure/app-service-announcements-discussions#37) - but even when I manually copied the correct version of System.Net.Http.dll into my application's directory it still failed (with and without the binding redirect), plus I was concerned about the hardcoded assembly reference. Given I also had System.Net.Http as a NuGet package I expected it to "just work" regardless of the deployment environment's .NET Framework version. I accept (in my particular case, at least) it's primarily a PEBCAK-class problem with an RTFM solution.
Member

### joperezr commented Oct 2, 2018

 placing a version of an assembly and adding a binding redirect is in most cases not enough, since you would have to also copy all of the new assemblies that the new System.Net.Http assembly references and uses at runtime. Most of the framework is tightly coupled, which means that it is hard to just pick different pieces of it from different versions and expect things to just work.

Closed

### hemelend commented Nov 9, 2018

 I resolved issue installing Microsoft.Rest.ClientRuntime package version 2.3.14

Closed

Open

Closed

Closed

Closed

Closed

Open

Closed

Closed

Closed

Closed

Closed

Closed

Closed

Closed

Open

Closed

Open

Closed

Closed

Closed