Runtime: System.Net.Http v4.2.0.0 being copied/loaded from MSBuild tooling

Created on 7 Dec 2017  ·  99Comments  ·  Source: dotnet/runtime

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.

area-Infrastructure-libraries bug packaging

Most helpful comment

what a nightmare!

All 99 comments

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.

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.

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

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!

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

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.

Also, Can you confirm that getting v4.2.0.0 referenced from C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\MicrosoftMicrosoft.NET.Build.Extensions\net461\libSystem.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.

HttpIssue.zip

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

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.

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.

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

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

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?

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?

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.

@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

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

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

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

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.

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

@onyxmaster Huh, if I understand https://github.com/Microsoft/msbuild/issues/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?

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.

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

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

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.

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!

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

There are no “offending packages” per se, if I understand correctly. It’s a set of msbuild rules that handle a dependency on netstandard for net4xx projects.

We never got this to work using binding redirects. The two assemblies does not seem to be compatible with each other. We ran into issues regardless of whether we redirected to 4.2.0.0 or 4.0.0.0. This either resulted in assembly load errors or "method not found" exceptions, both at runtime.

I get worried by @joperezr comment that 15.6 will "solve" this issue by adding binding redirects. This change alone will not help if the 4.2.0.0 assemblies are copied to the output folder and thus deployed with the application.

Is there really no one around that can give a clear answer on the purpose of the 4.2.0.0 files and why they are getting copied to the output folder when they should not be needed?

Binding redirects to 4.0.0.0 (https://github.com/dotnet/corefx/issues/25773#issuecomment-350000563) should help.
If they don't please post a minimal repro showing how it does not work. I can then chase down the right experts to get to the bottom of the problem.

@karelz Binding redirects did not help me. I gave a repro to @joperezr

Can you share the repro here? (minimized)

https://github.com/sokket/http_repro

This is a Service Fabric service with a .NET Core library referenced. The Core library has one function and references System.Net.Http; the fabric calls this function and throws

@sokket I talked with @joperezr and he mentioned Service Fabric is doing some specific steps which are likely the root cause.
I am curious if anyone else saw the workaround NOT working outside of Service Fabric. That would be worrisome.

I'm dealing with the issue in a Cloud Service project currently. So far, binding redirects don't seem to have any affect (4.2.0.0 is copied to bin/debug folders).
I also get this warning here, but I'm not 100% sure yet which project generates it (it doesn't show up on each rebuild):

C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\Microsoft.Common.CurrentVersion.targets(2154,5): warning MSB3836: 
The explicit binding redirect on "System.Net.Http, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" conflicts with an autogenerated binding redirect.
Consider removing it from the application configuration file or disabling autogenerated binding redirects.
The build will replace it with: "<bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.2.0.0" xmlns="urn:schemas-microsoft-com:asm.v1" />".

I will try to reproduce the issue we had with method not found exception, but in the meantime I upload two extremely simple projects that illustrates the issue we have with additional assemblies being copied to the output folder. Both are created in Visual Studio 15.5.4 using the normal New Project wizard, Visual C# Console App (.NET Framework), with target .NET 4.7.1. The only thing I have done is adding one line of code to Main to create a HttpClient, and adding a NuGet reference to System.Threading.Tasks.Dataflow.

In this project I use Dataflow 4.7.0: WithDataflow470.zip

In this project I use Dataflow 4.8.0: WithDataflow480.zip

I have zipped the projects as I get them when I build, so you can see the binaries. The output folder for the first project contains only two binaries, the project .exe and the System.Threading.Tasks.Dataflow.dll.

In the second project the output folder contains 12 additional assemblies that should not be there. They all have names starting with System. No binding redirects are created, since there are no conflicts. If I don't deploy the additional files the application won't runt - file load exceptions. If I deploy them, I will have to do manual assembly redirects to handle conflicts with other packages. And how are we supposed to know which assemblies we must redirect? Trying to get this right, by hand, in our solution with almost 200 projects is impossible

In Visual Studio I get the reference to System.Net.Http v4.0.0.0 immediately when I create the project. When I add the Dataflow 4.7.0 nuget package this is still the case, but as soon as I add the 4.8.0 version of that package the reference to System.Net.Http (as seen in Properties in VS) changes to v4.2.0.0 and the path is changed from
C:\Program Files (x86)\Reference Assemblies\Microsoft\ Framework\.NETFramework\v4.7.1\System.Net.Http.dll
to
C:\Program Files (x86)\Microsoft Visual Studio\2017\ Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net471\lib\System.Net.Http.dll

Well, I'm at a loss. I've added binding redirects to every single project and set AutoGenerateBindingRedirects to false (even though I'm not sure whether that actually works).

The same warnings are logged and 4.2.0.0 is copied to the bin/debug folder.
Here's a gist of a detailed build log with the conflict.
It says "System.Net.Http, Version=4.0.0.0, […]" was chosen because it was primary and "System.Net.Http, Version=4.2.0.0, […]" was not., lists all my projects as references to 4.2.0.0 despite binding redirects. At the end it says Found conflicts between different versions of "System.Net.Http" that could not be resolved. and uses the 4.2.0.0 version

I've found a workaround for non web projects. The MSBuild code that does the assembly replacement that is grieving us is near https://github.com/dotnet/sdk/blob/8a24663345cc5952062cb898431dbd8800b4da85/src/Tasks/Microsoft.NET.Build.Extensions.Tasks/msbuildExtensions/Microsoft/Microsoft.NET.Build.Extensions/Microsoft.NET.Build.Extensions.NETFramework.targets#L87, which gathers assemblies to be used as replacements for those that we have set on the project to fix versioning problems (how ironic) with older framework assemblies.

My project does not have any assembly with those versioning problems, so my fix was to upgrade all projects in the solution to .NET 4.7.1, reinstall all packages and set the DependsOnNETStandard property to false in my Directory.Build.props file:

<Project>
    <PropertyGroup>
        <AutogenerateBindingRedirects>true</AutogenerateBindingRedirects>
        <GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
        <DependsOnNETStandard>false</DependsOnNETStandard>
    </PropertyGroup>
</Project>

After that everything builds fine, and the system works as expected.

Still working on the web project part.

@EnCey I am not sure what you mean by Cloud Service - is that special project type or just type of application?
What happens when you ignore the warning? Does it work?
If you managed to minimize the repro, please share it with us.

I finally made my web project work. Simply added a Target that runs after the ImplicitlyExpandNETStandardFacades target and replaces the replaced references by simple GAC references.

In my case I just need to remove System.IO.Compression, but System.Net.Http should work too.

    <Target Name="FixBadNetStandardFixUps" AfterTargets="ImplicitlyExpandNETStandardFacades">
        <ItemGroup>
            <Reference Remove="System.IO.Compression" />
            <Reference Include="System.IO.Compression" />
        </ItemGroup>
    </Target>

I'm not sure what other things I'd be breaking with this changes...I should only have problems with old assemblies that reference this assemblies which had bigger numbers before, and nothing more.

Crossing fingers.

@karelz it's an Azure Cloud Service project with one WorkerRole.

My current status is this: v4.2.0.0 is copied to bin/debug of each individual project, but since its CopyLocal is set to false, it doesn't end up in the bin/debug folder of the top-level project (the worker role), so it won't be deployed to Azure.

I'm worried that we might be getting runtime errors if some component uses v4.2.0.0 exclusive features, which I assume would be available at build time, but not in the cloud. I tried to change the binding redirects to 4.2.0.0 and deploy the DLL, to see if it would work with the newer version. I still got warnings about conflicts, so I changed the redirects back even though they don't have any effect. Currently testing with the 4.0.0.0 version that should be in GAC in the cloud.

I'll try to set up a minimal repo.

One thing I'm still wondering, since the fix is to use binding redirects: why does this 4.2.0.0 version exist in the first place, and why is there internal tooling that depends on that version instead of what you release to customers?

@stijnherreman if you check C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\Microsoft\Microsoft.NET.Build.Extensions in the file Microsoft.NET.Build.Extensions.targets there's a comment that basically explains that previous versions of the framework shipped with some assemblies that don't match the ones on the .NET Standard 2.0 support package. That makes it possible to have 4.7 and lower libraries that reference assemblies with higher numbers.

They try to fix this by replacing the referenced assemblies (even those on the GAC) by the assemblies existing on the Microsoft.NET.Build.Extensions folder, which causes all kinds of problems for me (and evidently other people).

I finally fixed my problems by reversing the work done on that .targets file by removing all the <Reference/> and <ReferenceCopyLocalPaths/> on a target on my Directory.Build.targets file. No redirect bindings necessary (and possibly compatibility problems if I use assemblies which reference other versions in the future).

@weshaggard @davidsh in my case (VS 2017, .NET 4.6.1 with several .NET Core projects built to target 4.6.1), the binding redirect alone does not do the trick. We have to manually remove the System.Web.Http assembly from the VS/MSBuildTools directory - only then the build system picks up the correct assembly version installed via Nuget package.
While this works fine in development, for our build infrastructure it's less then desirable (other projects that may fail because of our tricks).
Can you advise something for CI scenario? Will the fix affect the MSBuildTools as well?

@joperezr could you please take a look and see if your tooling changes will help with these issues?

I don't think that my tooling changes will help here since the ones we have been working on will only affect when you target 4.7.1 which doesn't seem to be the case. @chester89 can I get a bit more info on your specific issue? What errors are you getting at runtime? Which binding redirect did you add? I suppose you mean System.Net.Http instead of System.Web.Http? What framework do you have installed?

@joperezr System.Net.Http, yes. I'll give you detailed description in a bit

@joperezr I have VS 2017 15.5.7, .NET 4.7 is the latest framework installed on the machine (although I installed it about a week ago, not sure if it affected the situation).
I have .NET Core SDK 2.1.4 with runtime versions 1.0.5, 1.1.2, 2.0.5.
We have a solution compiled for .NET 4.6.1, and then there's a library we use that targets .NET Standard 2.0. As I mentioned before, all projects use System.Net.Http 4.3.3 from nuget. If the only thing I do is add a binding redirect to 4.1.1.2 (and NOT move System.Net.Http.dll away from C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib folder) - I got this error when launching a web site: System.IO.FileLoadException Can not load file or assembly System.Net.Http, Version=4.1.1.2, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. HRESULT: 0x80131040.

@chester89 what if you don't add any binding redirects manually? I would expect the tooling should copy a version of System.Net.Http manually to your app's bin folder ( I might be wrong but I believe version should be 4.2.0.0) and then it should automatically add a binding redirect to it for you, so you shouldn't have to do this manually nor delete the one from the bin folder. Can you confirm that you have 4.2.0.0 version of System.Net.Http on your bin folder and that this works by just removing the manual binding redirect?

@joperezr sorry, I didn't provide the whole problem' description.
the reason I caught this error was due to the fact that we had several System.Net.Http dll versions in our solution (4.2.0.0 and 4.0.0.0, which can be found at C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5).
I was doing some refactoring and caught the issue - MethodMissingException was thrown when calling new HttpClient(new MyCustomHandler(new HttpClientHandler()). I investigated and decided to use one common version of System.Net.Http across all projects - 4.3.3 from nuget. Couldn't get this working without a redirect - got FileLoadException (see my first message)

@joperezr as for which dll version ends up in a bin folder:

  • before I did any of these changes (when we had 2 different versions of System.Net.Http in the solution, both from local machine, not from nuget) - I get 4.2.0.0 in my bin folder
  • after changes (using package 4.3.3 from nuget with binding redirect) - I get 4.1.1.2

For anybody still hitting this, we shipped today a version of VS 15.6.3 that contains the tooling fixes for this, so automatic binding redirects should now get generated for you that should fix most of these types of issues. Let me know if that is not the case

Thanks @joperezr!

It works no matter which framework we target?

On Tue, Mar 20, 2018, 19:10 Jonathan Miller notifications@github.com
wrote:

Thanks @joperezr https://github.com/joperezr!


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/dotnet/corefx/issues/25773#issuecomment-374656820,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AALnfIxXkLLt4CQHJnnH18Bk5zynnQtVks5tgSoEgaJpZM4Q5EF8
.

@joperezr
On Tue, Mar 20, 2018, 20:17 Gleb Chermennov thebitterend77@gmail.com
wrote:

It works no matter which framework we target?

On Tue, Mar 20, 2018, 19:10 Jonathan Miller notifications@github.com
wrote:

Thanks @joperezr https://github.com/joperezr!


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/dotnet/corefx/issues/25773#issuecomment-374656820,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AALnfIxXkLLt4CQHJnnH18Bk5zynnQtVks5tgSoEgaJpZM4Q5EF8
.

@joperezr
Automatically creating binding redirects is not proper fix for this bug.
It should never ever update references to higher version without good reason.

P.S. Frankly this whole AutoUnify thing is sound like bug to me. It should be at least optional.

@joperezr
I have now tested the simple projects I uploaded on Jan 18 with Visual Studio 15.6.3, and the issue is still there. Sure, we get a lot of binding redirects to later assembly versions, but that is in no way a solution for the problem. Dataflow 4.8.0 that I used to easily reproduce the problem has NO DEPENDENCIES, but the tooling copies 12 assemblies to the output folder when I target .NET Framework 4.7.1, and none of them are supposed to be there since I have them as part of the .NET Framework already.

Adding assemblies and redirecting to 4.2.0.0 is wrong, because .NET Framework 4.7.1 already fulfills .NET Standard 2.0 with its own assemblies, and those assemblies have version 4.0.0.0 as always to support in-place upgrades of the framework.

Has anyone even bothered to look at the projects I uploaded where the problem can be easily reproduced?

@ma-jo do you have a solution that we can look at?

The 12 files added to your output are correct. Due to a bug in the 4.7.1 support of .Net Standard 2.0 those files are required in the bin folder (along with binding redirects)

@AlexGhiondea I have already attached two solutions to this thread, see my post from January 18.

So are you saying that @davidsh and others are wrong when they previously stated that the versions in the GAC should be used?

If there are bugs in .NET Framework 4.7.1, why isn't that fixed instead of trying to work around the issue with additional files and redirects? Can you give any details about what bugs you are referring to? Is this behavior documented somewhere?

Let me try to explain why this is a big issue for us, besides the fact that it is has proved nearly impossible to get all the binding redirects and files correct. We develop a very complex medical application with strict requirements on patient safety, data security and so on. If we start to include major parts of .NET Framework as part of our products, what happens if a security issue is found in .NET Framework, let's say in System.Net.Http? Microsoft will typically do a KB and release a hotfix to be installed on the affected machines. But if we have distributed that file as part of our products, it will not benefit from the fix. Even building and deploying a new version of our product quickly cannot be done, since the affected file is part of MSBuild so we must wait for new tooling to be released before we can do it. That is totally unacceptable.

And what will happen when the next version of .NET Framework is released, let's say 4.8? I expect that to be an in-place upgrade again, just like the last couple of versions. Can you guarantee that the 4.2.0.0 versions of the files that we were forced to deploy are still compatible with the rest of .NET Framework 4.8? To me it sounds like we would be running on a very shaky platform with a mix of assemblies from two different versions that has never been tested together.

Hey @ma-bjo. I am really sorry you are hitting this issue.

Here is a bit more explanation of the problem we had with the support of .Net Standard on .NET Framework 4.7.1. .NET types live in different assemblies depending on the framework you are running in. A simple example would be the class String, which lives in mscorlib.dll on .NET framework, in netstandard.dll when you target .NET Standard 2.0, in System.Runtime.dll when you target .NET Standard 1.x, and in System.Private.CoreLib.dll on .Net Core. In order to have a library targeting one framework to successfully load when running on a compatible one, we sometimes need runtime facades (with type-forwards) which help us re-route the references to the all of the types that live on different places.

When we shipped .NET Framework 4.7.1 we intended to ship all of these runtime facades as well, but we ended up having some bugs in them that would cause some types to not get forwarded correctly. Because of the way we internally build and ship .NET Framework patches, it is not trivial to just service these runtime facades – e.g. some of the fixes also require changes in CLR. Moreover, the applications would require the patch to be installed on end-user machines.

Out of the 12 assemblies(runtime facades), we add to your bin folder, 9 of them don’t contain any code, just type forwarders. The remaining 3, contain a little bit of code, but mostly they are also just type-forwarders into .NET Framework assemblies.

We understand the pain you are going through and we are making sure that .NET 4.7.2 doesn't have any of this type of issues by doing extensive testing (incl. exercising each type in .NET Standard when running on .NET Framework).

Thanks @joperezr for finally explaining the details! I'm still very troubled by this, but at least it is starting to make sense now.

Just for completeness, are the 12 runtime facades in my example all the assemblies that had buggy facades in .NET 4.7.1, or can we expect more?

Will the 12 facades always be added to the output folder when referencing a library targeting .NET Standard 2.0, or is it affected by for example the transitive dependencies of the library?

Or let me put it like this: Is the proper fix to always deploy the 12 facades and add the 12 forward binding redirects to every exe, web site and unit test assembly in my solution?

Just for completeness, are the 12 runtime facades in my example all the assemblies that had buggy facades in .NET 4.7.1, or can we expect more?

They are all of them. We don't expect to find any additional ones and we have done testing to ensure this is the case.

Is the proper fix to always deploy the 12 facades and add the 12 forward binding redirects to every exe, web site and unit test assembly in my solution?

As long as your app has some dependency that is .NET Standard based (.NET Standard 2.0 or 1.x) you will need the 12 facades and the binding redirects. We have logic in our tooling that will basically walk all of your dependencies in order to determine if this is the case or not, and if it is, then we will drop the facades to your bin folder and then add the binding redirects to your app's config file.

@joperezr https://github.com/joperezr I'll try the new VS version on
Monday. Meanwhile, what's your advice to get this working on build machines?

2018-03-22 19:54 GMT+03:00 Jose Perez Rodriguez notifications@github.com:

Just for completeness, are the 12 runtime facades in my example all the
assemblies that had buggy facades in .NET 4.7.1, or can we expect more?

They are all of them. We don't expect to find any additional ones and we
have done testing to ensure this is the case.

Is the proper fix to always deploy the 12 facades and add the 12 forward
binding redirects to every exe, web site and unit test assembly in my
solution?

As long as your app has some dependency that is .NET Standard based (.NET
Standard 2.0 or 1.x) you will need the 12 facades and the binding
redirects. We have logic in our tooling that will basically walk all of
your dependencies in order to determine if this is the case or not, and if
it is, then we will drop the facades to your bin folder and then add the
binding redirects to your app's config file.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/dotnet/corefx/issues/25773#issuecomment-375378550,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AALnfKr4h89WHBHhbIw11IZnDSQE-ciGks5tg9dCgaJpZM4Q5EF8
.

--
Yours faithfully,
Gleb

what a nightmare!

I'll try the new VS version onMonday. Meanwhile, what's your advice to get this working on build machines?

I would either try to get build machines on latest VS tools, or if that is not possible then perhaps I would manually add the binding redirects for now on the app.config until the VS tools get updated.

What redirect @joperezr are you suggesting we add? a redirect back to the 4.0.0.0 versions? or a redirect to 4.2.0.0 ? This has broken our build machine.

WARNING:
C:\Program Files (x86)\Microsoft Visual
Studio\2017\Community\MSBuild\15.0Bin\Microsoft.Common.CurrentVersion.targets(2052,5): Warning MSB3243: No way to resolve conflict between "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". Choosing "System.Net.Http, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" arbitrarily.

ERROR:
Error CS0433: The type 'HttpClient' 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'

4.2.0.0. Best way to figure out which ones to add manually to your app.config would be to build your project locally, and then checking the resulting config file that gets dropped into the bin folder and check which binding redirects where added there. Those should be the same ones that you add to the App.config since build machines won't be adding them automatically if they don't have an up-to-date VS installed.

@joperezr Everything builds locally, it's when it's when push our code to the build server everything breaks with msbuild. And the tooling did not "automatically" add anything. I have spent the last 3 days trying to fix the mess from upgrading visual studio and trying to target 4.7.1 . I have redirects in all the app.configs for this:

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

Also the build machine is updated to the latest version of the tooling.

Is this a ASP.NET Web Application project? If so, please take a look at my comment here

Targeting Framework 4.6.1, and was wondering:
Couldn't a newer NuGet package get released, with 4.2.0.0 in it?

I am confused where the latest DLLs come from. System.Net.Http 4.2.0.0 (the highest version number) comes from
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib
Yet for other libraries like System.Security.Cryptography.Algorithms the above folder is lower (4.3.0.0) than NuGet (4.3.1.0). I thought the whole idea of using NuGet is to not have DLL hell, and pretty much always have the latest versions. A newer NuGet for System.Net.Http would do that, right?

Right now I have most of my projects including
<package id="System.Security.Cryptography.Algorithms" version="4.3.1" targetFramework="net461" />
which sucks, but is probably more future-proof than me manually uninstalling all the System.Security.Cryptography.* packages, and manually adding references back to the
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib
folder.

If the logic applies for those, why not use the same logic for System.Net.Http?

@ColinNg Our goal is not to release the System.Net.Http NuGet package ever again. We would even delete it / reship empty one if it wouldn't break way too many customers (we discussed these options quite a lot a year ago).
You should not need to explicitly reference Microsoft.NET.Build.Extensions\net461\lib directory. VS tooling should take care of that for you. You should not need explicit bindingRedirects, once you have fixed VS tooling - they will be generated for you.

I'm targeting 4.6.2

I have upgraded to VS2017 version 15.6.3 and I am still having issues with this. Although binding redirects are being added they refer to version 4.1.1.2 when version 4.2.0.0 is still being delivered during a build. I solved this by removing the redirects all together but this is a manual step i would like to avoid.

@karelz the VS tooling is not taking care of it, as people are reporting issues. see this link https://github.com/dotnet/sdk/pull/1712#issuecomment-377314726 posted earlier by
@joperezr

Currently this is broken for ASP.NET webprojects. I have to set a direct reference from our ASP.NET webproject because of all the errors and warnings, in addition the correct versions are not deployed into the azure environments (see link above). I am on Visual Studio 15.6.4 (updated last week).

I basically had to add the assembly redirects to everything. In addition, I had to copy the dll's (msbuild versions 4.2) to a folder in our source control so the TFS agent can get the right versions. This is because our TFS build server cannot properly resolve the hint "paths" that the "Tooling" is setting in our csproj file (one too many ..........\ and Professional vs Community) . Our build server uses Community Edition of Visual Studio vs our development machines (Professional). The tooling was hard-coding "Professional" in the csproj file hint path. Even while debugging (on our TFS build server) the path the tooling is setting is off a directory level (too many ..); as a result, msbuild would resolve to version 4.0 and could never find version 4.2 (fail!)

So with the current state of affairs is it safe to say there are basically three different versions of System.Net.Http, and there is no fix for ASP.NET Webprojects?

So now I must fight the tooling as it making the wrong choice.

@armitagemderivitec does your scenario use ASP.NET webprojects? If not and you are still hitting problems, please file a new issue with repro description - tag @joperezr there and he will help to find solution and workarounds if necessary. Thanks!

@jwisener I wasn't aware of the remaining problems with ASP.NET webprojects - apparently some scenarios are not fully working yet. @joperezr and @AlexGhiondea are working hard on that (it is slightly different problem than the original one reported here) - they are bringing in the right people who need to be involved to get it solved and they will be happy to help you with workarounds in the meantime.

Given that this issue is now mix of several different problems with similar symptoms and given that the original problem has been solved, I would recommend to:

  1. Close this issue.
  2. File a new issue for the ASP.NET webproject problem and discuss its details there (incl. workarounds).
  3. Ask anyone who has similar symptoms not solved by latest VS tooling to file a new issue (with repro and/ or logs), so that we can take a closer look - tag @joperezr on such issues.

That should hopefully provide some clarity on which problems are solved, which have pending fixes, what are their workarounds, how much pain they are causing, etc.

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

Same for us

On Wed, Apr 4, 2018 at 5:33 AM armitagemderivitec notifications@github.com
wrote:

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


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/dotnet/corefx/issues/25773#issuecomment-378555292,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAISTm3Y0O-dI-E3zNCWK0gUpamqhER6ks5tlKFygaJpZM4Q5EF8
.

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.

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.

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

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

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.

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

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\MicrosoftMicrosoft.NET.Build.Extensions\net461\libSystem.Net.Http.dll) 4.2.0.0 overrides the latest 4.1.1.2 (from 4.3.3 System.Net.Http nuget package)

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

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.

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

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

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

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:








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.

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

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

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

@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: https://github.com/Azure/app-service-announcements-discussions/issues/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.

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.

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

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)

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sahithreddyk picture sahithreddyk  ·  3Comments

GitAntoinee picture GitAntoinee  ·  3Comments

iCodeWebApps picture iCodeWebApps  ·  3Comments

yahorsi picture yahorsi  ·  3Comments

Timovzl picture Timovzl  ·  3Comments