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

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

Closed
camp-007 opened this issue Dec 7, 2017 · 99 comments
Closed

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

camp-007 opened this issue Dec 7, 2017 · 99 comments
Assignees
Milestone

Comments

@camp-007
Copy link

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.

https://github.com/dotnet/corefx/issues/22781#issuecomment-322691420

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:

  1. Using VS Enterprise 15.5, create a new console app 'ConsoleApp1' that targets .net 4.6.1
  2. Create a new class library 'ClassLibrary1' that targets .net 4.6.1
  3. ConsoleApp1 references ClassLibrary1
  4. Add nuget package System.Net.Http v4.3.3 to ConsoleApp1
  5. Add nuget package System.Net.Http v4.3.3 to ClassLibrary1
  6. ClassLibrary1.Class1 needs to instantiate HttpClient and ConsoleApp1.Program needs to instantiate HttpClient and ClassLibrary1.Class1
  7. 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
  8. Add nuget package System.Collections.Immutable v1.4.0 to ClassLibrary1
  9. 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:

  <runtime>
    <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.1.1.2" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>

But it seems incorrect to have to redirect backwards like that.

@camp-007
Copy link
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: https://github.com/dotnet/corefx/issues/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.

@davidsh
Copy link
Contributor

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.

  <runtime>
    <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.0.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>

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.

@davidsh
Copy link
Contributor

davidsh commented Dec 7, 2017

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

@camp-007
Copy link
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!

@camp-007
Copy link
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?

@davidsh
Copy link
Contributor

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.

@davidsh
Copy link
Contributor

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.

@camp-007
Copy link
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
Copy link

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
Copy link

natelaff commented Dec 11, 2017

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
Copy link

ma-bjo commented Dec 14, 2017

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.)

@camp-007 camp-007 changed the title System.Net.Http v4.3.0.0 being copied/loaded from MSBuild tooling System.Net.Http v4.2.0.0 being copied/loaded from MSBuild tooling Dec 15, 2017
@camp-007
Copy link
Author

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

@stijnherreman
Copy link
Contributor

stijnherreman commented Dec 18, 2017

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
Copy link
Contributor

stijnherreman commented Dec 19, 2017

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
Copy link

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
Copy link

@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
Copy link

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.

@davidsh
Copy link
Contributor

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.

@weshaggard
Copy link
Member

@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
Copy link

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
Copy link

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.

@onyxmaster
Copy link

Setting property <ImplicitlyExpandNETStandardFacades>False</ImplicitlyExpandNETStandardFacades> for 4.7.1 projects helps. This might break unknown other things though.

@stijnherreman
Copy link
Contributor

stijnherreman commented Jan 15, 2018

@onyxmaster Huh, if I understand dotnet/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?

@onyxmaster
Copy link

Yes, I’ve seen the issue you mentioned, hence the warning that it might break something unknown. In my case (a 180+-project solution combining lots of legacy code) everything works okay, but probably because we do not reference any problematic nuget packages. I guess the outcome much depends on projects’ dependencies.

@onyxmaster
Copy link

I’m for sure looking for a proper fix for this, but it’s much more manageable for a team to add a property to a common property file shared among all projects (we have one, and even if we hadn’t, there is Directory.Build for that), than to remove the msbuild.extensions file on every build system :)

@onyxmaster
Copy link

onyxmaster commented Jan 15, 2018

My actual problem (linked above) is actually solvable by binding redirects, but I really hate when something breaks the established API contract (with exceptions, in my point of view, being the most important part of them, since they are discoverable only at runtime).

@joperezr
Copy link
Member

It might, in fact, break some things if you set the property, which is why the temporary suggested solution is to add binding redirects. New changes have gone into the VS tooling that will be released on VS 15.6 Preview 3 that will generate the right binding redirects for you. For the time being, unfortunately, that needs to be done manually to fix these issues.

@onyxmaster
Copy link

Adding binding redirects doesn’t play well with projects that have automatic binding redirects enabled (test projects in our case), so I opted for the property. I have 15.6P2 installed, will test when/if P3 fixes the problem. Thanks for the heads-up!

@stijnherreman
Copy link
Contributor

@joperezr Is it not an option to fix the offending packages that reference this 4.2.0.0 version? Either way, I sincerely hope that 15.6 will finally have resolved all problems.

@m17kea
Copy link

m17kea commented Apr 4, 2018

@karelz @joperezr my issues are indeed with Asp.Net web projects, we have both an API and MVC site with the issue

@jwisener
Copy link

jwisener commented Apr 4, 2018 via email

@karelz
Copy link
Member

karelz commented Apr 4, 2018

Thanks for confirmation @armitagemderivitec @jwisener.
@AlexGhiondea @joperezr do you want to create a new bug to track the ASP.NET web project bug? Then we can close this one.

@SamNutkinsP
Copy link

SamNutkinsP commented Apr 4, 2018

I'm seeing this issue as well (using VS 15.6.4).

I have a .NET 4.7.1 class library referencing a nuget package that has a reference to a .NET Standard 2 component. The class library is referenced by a Windows Forms application, although I'm not sure that is relevant because these 12 System.* assemblies are deployed to the bin folder when only the class library is built.

@rokleM 's suggestion of adding <DependsOnNETStandard>false</DependsOnNETStandard> to the class library worked, but only in the sense that my application runs correctly without these assemblies deployed alongside. The assemblies are output to the bin folder regardless of this change. For now, it seems I can just make this change and continue to not deploy these assemblies.

Does this align with everyone's findings? It seems like the general consensus is that this shouldn't be happening in the latest version of VS, but it is.

Hopefully this helps someone.

@ColinNg
Copy link

ColinNg commented Apr 4, 2018

Thanks @karelz for the explanation. I will notify these two package maintainers who are including the NuGet package for System.Net.Http as a dependency.

https://www.nuget.org/packages/Google.Apis/
https://www.nuget.org/packages/Sendgrid

@AlexGhiondea
Copy link
Contributor

@SamNutkins those 12 files present in the bin folder are expected if you are targeting 4.7.1. We have documented this as a known issue here.

@joperezr will file a separate issue for the asp.net web projects issue.

@joperezr
Copy link
Member

joperezr commented Apr 5, 2018

Created dotnet/corefx#28833 to track the ASP.NET scenario and closing this one as previously discussed. @jwisener @ColinNg feel free to chime in on that one in case I missed anything so that we have all the info when coming up with fixes/workarounds.

@joperezr joperezr closed this as completed Apr 5, 2018
@philcarbone
Copy link

This is occurring for us in Service Fabric projects as well as ASP.NET projects (and the bindings need to be flipped if we run EntityFramework migrations in the Package Manager Console. Then flipped back if we want to run our app). Also, every time a package updates it reverts to a binding we DON'T want, it is super annoying and all of our developers are frustrated with it - myself included ;)

@stevozilik
Copy link

Please fix, this is same problem for us.

Running Service Fabric with Asp Net Core, the System.Net.Http (from C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Net.Http.dll) 4.2.0.0 overrides the latest 4.1.1.2 (from 4.3.3 System.Net.Http nuget package)

@karelz
Copy link
Member

karelz commented Apr 11, 2018

@joperezr is Service Fabric the same problem, or do you need a new issue filed with new repro for investigation?

@joperezr
Copy link
Member

From the first look it doesn't seem to be the same issue although it looks similar. @stevozilik do you mind opening a new issue with more info so we can take a look at your scenario? If you have minimal repro that would be ideal, but if not, try to at least include info like the framework you are targetting, VS you are using, and some info on the way you are publishing. Also getting details on the exception would help.

@eiriktsarpalis
Copy link
Member

Seeing the same issue in VS 15.7 Preview 5 using net461 class libraries and console applications.

@joperezr
Copy link
Member

joperezr commented May 4, 2018

@eiriktsarpalis do you mind sharing a small repro so that we check what is going on? net461 shouldn't have this problem at all since the runtime facades have been injected successfully for many VS releases so I'm interested in understanding more about your scenario.

@smaine
Copy link

smaine commented Sep 29, 2018

Here's what I've learned from debugging this issue in a nontrivial codebase, in case it's helpful to others.

The root cause of the issue is when you are targeting the desktop framework (e.g TargetFrameworkVersion=v.4.61) and you pick up a dependency on a Nuget package whose dependency metadata only includes dependency information for NetStandard. The bad package can be picked up either directly or transitively, which makes the root cause of these compile-time assembly resolution errors very difficult to isolate.

In our case, we had picked up a transitive dependency on System.Buffers v4.4.0. The NuSpec for this version only contains <group targetFramework=".NETStandard2.0" /> and is missing the critical tag <group targetFramework=".NETFramework4.5" />. This causes MSBuild to consider this package as carrying a transitive reference to the NetStandard version of System.Net.Http (4.2.0). The unifier observes that this version is higher than the GAC version (4.0.0) and unifies to 4.2.0 which causes numerous downstream ambiguous references.

Fortunately, this bug seems to have been noted and corrected in System.Buffers 4.5, which correctly declares dependencies for both NetStandard2.0 and .NETFramework4.5. We resolved the compile-time ambiguity by adding an explicit PackageReference to v4.5.0 of System.Buffers to override the transitive dependency on the bad version we had picked up through one of our direct dependencies. Because we were compiling against the correct version, we did not need to add any app.config assembly redirects to resolve ambiguity at runtime.

It's not clear how many libraries beyond System.Buffers have this problem, but it's probably a non-zero set. If you're a library author and have a dependency on V4.4 of System.Buffers, all the people writing desktop apps against your library would greatly appreciate you moving to V4.5 as soon as possible :)

@daiplusplus
Copy link

daiplusplus commented Oct 2, 2018

I'm having the same issue, except I noticed that the output DLL from my project (ASP.NET Core 2) has a hard reference to 4.2.0.0 of System.Net.Http that I can see in .NET Reflector, even though I don't have a project reference to that at all.

My project runs fine on my PC (naturally), and when deployed to Azure App Services (Azure Websites) it fails with that same error (I modified my project to instantiate an instance of System.Net.Http.HttpClient during App-startup so it fast-fails):

FileNotFoundException: Could not load file or assembly 'System.Net.Http, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.

Screenshot proof:

image

  • I have the following binding-redirect in my web.config however it does not fix the problem at all, the exact same exception happens:

    <runtime>
      <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.1.1.2" />
        </dependentAssembly>
      </assemblyBinding>
    </runtime>
    

Update:

If I change my csproj (just for this ASP.NET Core 2 project) to target .NET Framework 4.7.1 instead of 4.7.2 and also add this to my csproj (so it builds), then it seems to work. I'm also able to remove the binding-redirect from web.config with no apparent ill-effects.

<PropertyGroup>
    <TargetFramework>net471</TargetFramework>
    <ResolveAssemblyReferenceIgnoreTargetFrameworkAttributeVersionMismatch>true</ResolveAssemblyReferenceIgnoreTargetFrameworkAttributeVersionMismatch>
</PropertyGroup>

Fortunately I'm not using any of the new functionality in .NET 4.7.2.

@wuwei26
Copy link

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...

@karelz
Copy link
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)

@joperezr
Copy link
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.

@daiplusplus
Copy link

daiplusplus commented Oct 2, 2018

@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.

@joperezr
Copy link
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.

@hemelend
Copy link

hemelend commented Nov 9, 2018

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

yecli referenced this issue in VirtoCommerce/vc-module-webhooks Nov 25, 2019
- Updated platform dependency to 2.13.53 for having System.Net.Http redirect. Otherwise Polly cannot be loaded on .Net 4.6.1:
- App-vNext/Polly#668;
- https://github.com/dotnet/corefx/issues/25773;
@msftgits msftgits transferred this issue from dotnet/corefx Jan 31, 2020
@msftgits msftgits added this to the 2.1.0 milestone Jan 31, 2020
@atomaras
Copy link

atomaras commented Apr 24, 2020

I have wasted endless days fighting this..
In my case one of the culprits is System.Net.Http.WinHttpHandler v4.7.0 (references 4.2.0.0 of system.net.http)
Adding manual redirects is simply not an option for us after we migrated to Nuget.
I noticed that Asp.Net 4.6.2 Web Projects fail to find the 4.2.0.0 version in order to copy it into the output (even though the automatic redirect ends up being 4.2.0.0) because they never look inside the NETBuildExtensions folder...All our console and class lib projects work fine i.e they end up with 4.2.0.0 redirect AND the 4.2.0.0 file on disk)
We have autogenerateBindingRedirects set to true. What I don't understand is why although msbuild decided to use/copy the lower version 4.1.1.3 of system.net.http the generated redirect is for 4.2.0.0. Which results in our app crashing at runtime because obviously the redirect for 4.2.0.0 is wrong since the file on disk is 4.1.1.3.

I just want to get back to coding please :(

P.S i ended up making my own msbuild custom task to workaround most of its shortcomings (transitive deps, assembly resolution etc etc)

@akempe
Copy link

akempe commented Nov 27, 2020

This is still an absolute clusterfuck... and the rollout of .net 4.8 to azure appservice has introduced more problems. the EXACT same project (which has been fine for months without any changes) deployed to 2 different appservice plans now behaves differently. To make matters worse, scaling the appservice up/down often fixes the problem for a few days. I know you can't fix it - made clear by how long this doom-scroll of a thread is - but I hope others having this issue know they're not alone.

@ghost ghost locked as resolved and limited conversation to collaborators Dec 27, 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