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

Cannot resolve conflicts with System.Net.Http when referencing a 4.7.2 project from a .NET Standard 2 project #27514

Closed
WillSullivan opened this issue Oct 1, 2018 · 20 comments
Milestone

Comments

@WillSullivan
Copy link

Minimal repro here https://github.com/WillSullivan/System.Net.Http.Hell

I'd like to have a solution to get that warning out of my build. If this were the other way around (4.7.1 referencing the .NET Standard 2 project) I could just slap a binding redirect in the .config file (and go take a Silkwood shower). But I haven't found any equivalent for .NET Standard projects. I'm at a dead end.

From the readme.md file at the repro:

This project illustrates how referencing a 4.7.2 project from a .net standard 2.0 project where System.Net.Http is involved triggers the following warning on build

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

The diagnostic build details

There was a conflict between "System.Net.Http, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" and "System.Net.Http, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
    "System.Net.Http, Version=4.1.2.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.
    References which depend on "System.Net.Http, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" [C:\Users\wsullivan\.nuget\packages\netstandard.library\2.0.3\build\netstandard2.0\ref\System.Net.Http.dll].
        C:\Users\wsullivan\.nuget\packages\netstandard.library\2.0.3\build\netstandard2.0\ref\System.Net.Http.dll
          Project file item includes which caused reference "C:\Users\wsullivan\.nuget\packages\netstandard.library\2.0.3\build\netstandard2.0\ref\System.Net.Http.dll".
            C:\Users\wsullivan\.nuget\packages\netstandard.library\2.0.3\build\netstandard2.0\ref\System.Net.Http.dll
    References which depend on "System.Net.Http, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" [].
        D:\GitHub.Com\System.Net.Http.Hell\System.Net.Http.Hell\bin\Debug\System.Net.Http.Hell.dll
          Project file item includes which caused reference "D:\GitHub.Com\System.Net.Http.Hell\System.Net.Http.Hell\bin\Debug\System.Net.Http.Hell.dll".
            D:\GitHub.Com\System.Net.Http.Hell\System.Net.Http.Hell\bin\Debug\System.Net.Http.Hell.dll

Adding the following to the .Net standard project file has no effect

<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
@karelz
Copy link
Member

karelz commented Oct 1, 2018

@joperezr can you please take a look?

@GSPP
Copy link

GSPP commented Oct 2, 2018

System.Net.Http is causing some trouble currently. I'm on .NET 4.7.1 Desktop, targeting 4.7.1 as well. I had two projects with B depending on A. I was able to make it work by making B reference the framework (<Reference Include="System.Net.Http">) and A use the nuget reference:

    <Reference Include="System.Net.Http, Version=4.1.1.2, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
      <HintPath>..\packages\System.Net.Http.4.3.3\lib\net46\System.Net.Http.dll</HintPath>
      <Private>True</Private>
    </Reference>

The compiler error in project A was something like "conflicting versions of System.NetHttp: 4.0.0.0 and 4.2.0.0".

No other configuration allowed me to compile. I do not understand what's going on so maybe somebody has an idea.

I also don't understand the many versions that are in play. The package is called System.Net.Http.4.3.3, apparently it contains v4.1.1.2 but I have seen binding redirects to 4.2.0.0. I admit I'm not a sophisticated NuGet user but there seems to be a problem here.

@WillSullivan
Copy link
Author

@GSPP you're experiencing the birth pains of the .NET framework supporting .NET Standard 2.0. Read this https://github.com/Microsoft/dotnet/blob/master/releases/net471/KnownIssues/514195-Targeting%20.NET%20Framework%204.7.1%20copies%20extra%20files%20to%20your%20bin%20directory.md Upgrading to 4.7.2 was supposed to fix this issue, but apparently it's still kicking, albeit in a different form.

Solutions for 4.7.1 include hiding the /lib folder in which the 4.2.0.0 binary exists, or have all assemblies reference the framework version (4.0.0.0) and use a binding redirect to 4.2 in the application that's referencing 4.2, and binding redirects to 4.0 in those assemblies that reference the 4.2 assembly (in our case our web application was 4.2 and everybody else was 4.0, including the test projects for the web assembly). The second option worked out better for us.

@GSPP
Copy link

GSPP commented Oct 2, 2018

@WillSullivan thank you.

For other people coming here I will leave a few notes:

I recommend to enable MSBuild logging as recommended here: https://stackoverflow.com/a/32633776 Then, delete all bin and obj folders, build and copy the build log to a file. That way you can make changes and use a diff tool to see the difference in behavior.

I also find out that binding redirects in web application projects do influence compilation which was surprising to me. The MSBuild log looks a bit like this:

Task "ResolveAssemblyReference"
...
3>  Unified primary reference "System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
3>      Using this version instead of original version "4.2.0.0" in "MyWebAppB\bin\Debug\B.dll"
because of a binding redirect entry in the file "Web.config".

My binding redirect was this:

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

I also found this which indicates that 3rd party DLL references are capable of introducing version conflicts:

3>  Unified Dependency "System.Net.Http, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
3>      Using this version instead of original version "4.0.0.0" in 
"A\bin\Debug\Google.Apis.YouTube.v3.dll" because of a binding redirect entry in the file "Web.config".

The MSBuild folder ("C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net471\lib\System.Net.Http.dll") contains version 4.2.0.0. The latest NuGet package has 4.1.1.2.

I tried making all references reference the NuGet package, specify the version 4.1.1.2 explicitly and add binding redirects to 4.1.1.2 everywhere. This fails. The MSBuild log weirdly says that the 4.1.1.2 version could not be found on disk. The HintPath was not used which I cannot explain. MSBuild apparently then proceeded to burn a 4.2.0.0 reference into A making the compilation of B (web app) fail. I cannot get it to use 4.1.1.2.

The HintPath being ignored was reported elsewhere as well: https://developercommunity.visualstudio.com/content/problem/296293/vs2017-1575-ignores-the-hintpath-and-take-the-syst.html

@GSPP
Copy link

GSPP commented Oct 2, 2018

I succeeded by doing this:

Make all references and binding redirects use 4.2.0.0 like this:

<Reference Include="System.Net.Http, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
  <HintPath>..\packages\System.Net.Http.4.3.3\lib\net46\System.Net.Http.dll</HintPath>
  <Private>True</Private>
</Reference>

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

The application now compiles and runs on .NET 4.7.1. All assemblies now reference 4.2.0.0.

The NuGet package contains 4.1.1.2 and wants to install that but you have to manually override to 4.2.0.0.

I believe this issue could be fixed through the NuGet package. It must configure 4.2.0.0 on .NET 4.7.1. Then, everything should automatically work.

@joperezr
Copy link
Member

joperezr commented Oct 2, 2018

@WillSullivan Do note that when targeting .NET Standard in your project and consuming .NET Framework libraries you are walking on the edge of unsupported territory. The original design is to have .NET Framework apps reference .NET Standard but not the other way around. Think of this way, when you target .NET Standard, then your library should run everywhere .NET Standard runs (for example: .NET Core, .NET Framework, Xamarin, Mono, etc.). If that library has a dependency on a component that only exists on one of those frameworks, you are kind of setting yourself up for failure. That said, we try to do our best and have your library to still produce something that will run on .NET Framework, but encountering warnings on builds because you have inconsistent versions of some assemblies is kind of a side effect of the scenario.

Upgrading to 4.7.2 was supposed to fix this issue, but apparently it's still kicking, albeit in a different form.

I'm curious as to why do you think that this specific problem is still around. When you target 4.7.2, we will not add any binding redirect to your app, and references to System.Net.Http.dll 4.2.0.0 should just work as we have some logic on the framework to use the one inbox in that case.

@WillSullivan
Copy link
Author

@joperezr

albeit in a different form.

There's oddness, and it's still something to do with System.Net.Http (the bane of my existence for the past forever months). I completely understand the netstandard-referencing-netframework "edge of unsupported territory." That makes complete sense, and it's not a wise design choice on our part. I'll pass that on and see if we can support our overall needs while avoiding this scenario.

@karelz
Copy link
Member

karelz commented Oct 3, 2018

Can we close the issue or is there still something pending here?

@GSPP
Copy link

GSPP commented Oct 3, 2018

@karelz what's the current plan to address the System.Net.Http.dll and System.Runtime.dll breakages? I don't necessarily mean this particular issue but all the ones that have been reported. There's a list in https://github.com/dotnet/corefx/issues/32587#issuecomment-426619079.

@WillSullivan
Copy link
Author

Well, I'm doing something that's supported (I'm assuming "edge of unsupported" means inside the line), and there's no way to get rid of the warning, apparently... is this a no-fix? Would it be worthwhile to add a warning when a netstandard assembly is referencing a framework assembly, and state that you may encounter warnings about inconsistent versions that cannot be resolved so don't go down that rabbit hole? Possibly pointing to guidance (if available)?

Ball's in your court, gentlemen.

@karelz
Copy link
Member

karelz commented Oct 3, 2018

@GSPP the plan is to keep understanding the root-causes as there are multiple problems with similar symptoms. And keep fixing them (many are fixed in latest VS tooling and .NET 4.7.2 AFAIK).
I suggested to @joperezr yesterday to create a wiki where we can keep list of known problems and where/how they were solved to streamline & load balance troubleshooting of these problems.
If you have better ideas, we are all ears.

@WillSullivan I would expect that referencing .NET Framework library project in .NET Standard library project will create warning in VS. Looks like that is not the case - @joperezr do you know if it is by design or a bug/oversight?
I am not certain what could/should be the behavior if you reference .NET Framework DLL from .NET Standard library project (depends if we can easily detect what it has been built against).
"Edge of unsupported" in this case means it may work with certain restrictions (incl. having permanent warnings you can't get rid of). I agree that it would be best to reference it in the warning.

@joperezr
Copy link
Member

joperezr commented Oct 3, 2018

@WillSullivan what I meant by "edge of unsupported" is that this is not really a supported scenario, but since users transitioning from .NET Framework into .NET Standard might hit issues like these, we tried our best to let your app compile and run if at all possible. Having warnings on the build, as @karelz suggests, is just some restrictions that our tooling will notice when things aren't really lining up perfectly(Like referencing two versions of the same assembly that target different frameworks which aren't supported between each other).

@GSPP
Copy link

GSPP commented Oct 9, 2018

@shadowmint
Copy link

@GSPP May I just say thank you for gathering all this information into one place? It's difficult to get an understanding of whats going on with this issue in all the multiple threads on multiple issue trackers about this topic, and this is extremely helpful.

@karelz please put some kind of authoritative documentation source somewhere about this issue. It's quite difficult to know where to report issues relating to it, or where to watch for updates relating to it.

For example, the latest VS tooling does exactly nothing to help me... should I report that as a bug? Should I post a repro of the issue? What issue tracker should that go to? Are there more fixes 'in the pipeline' or do you guys just think the latest VS tooling fixes this issue?

I know this is one of those nightmare bugs that has similar symptoms from many causes, but if you want to actually address the root cause, I think you need to make a slightly more coordinated effort to gather reproducible failure conditions, and document some kind of FAQ of 'try this first before posting a new issue about it'.

@GSPP
Copy link

GSPP commented Oct 10, 2018

I just upgraded to .NET 4.7.2 and I'm still hitting various issues. Definitely not fixed. PackageReference is not a viable option, either, because it does not support various things and also has some bugs (e.g. restart VS and all package references no longer show up).

I think it would not be too hard to fix all of these given that repros are available, and also given that it is very easy to trigger these issues with almost trivial usage of the product. I mean I almost find myself unable to use NuGet packages at this time. I'm not doing exotic things. In my other issue I did nothing more than "create project, add 2 packages, error". Very bad situation!

Also, other people are having these kinds of issues to the hundreds: https://www.google.com/search?q=%22Could+not+load+file+or+assembly+System.Runtime%22

@karelz
Copy link
Member

karelz commented Oct 11, 2018

@shadowmint I know this is one of those nightmare bugs that has similar symptoms from many causes, but if you want to actually address the root cause, I think you need to make a slightly more coordinated effort to gather reproducible failure conditions, and document some kind of FAQ of 'try this first before posting a new issue about it'.

That is exactly what I recommended to @joperezr last week - to create some kind of living-doc FAQ that would help troubleshooting (also to others on the team like me). He plans to do that.

@GSPP I think it would not be too hard to fix all of these given that repros are available

That is exactly what is happening - @joperezr is root-causing and addressing each new repro for the symptom class, after making sure it is not a dupe of existing known problem. Keep bringing up the repros.
The biggest challenge IMO is to keep the repros separate and avoid mixing issues together.

@GSPP
Copy link

GSPP commented Oct 12, 2018

@karelz I appreciate it!

@WillSullivan
Copy link
Author

I did recently cross this bit of interesting documentation

https://docs.microsoft.com/en-us/dotnet/core/porting/third-party-deps#net-framework-compatibility-mode

Which I think does adequately describe what's going on and offers a partial solution for those who have confirmed referencing a framework assembly doesn't break a netstandard project and want to clear out that warning message for a specific reference.

Considering the docs are out there, I'll close this issue.

@msftgits msftgits transferred this issue from dotnet/corefx Jan 31, 2020
@msftgits msftgits added this to the 3.0 milestone Jan 31, 2020
@umartopia
Copy link

I tried out various solutions (removing the dependentAssembly OR specifying the binding redirect as well). None of them worked.

However, the only solution which worked for me was to explicitly set Specific Version for System.Net.Http (or whatever DLL giving you version issues) to False from Visual Studio.

image

@chucklu
Copy link

chucklu commented Nov 19, 2020

@WillSullivan What's is the Platform:System.ValueTuple.dll? where can I find it?

Encountered conflict between 'Reference:System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL' and 'Platform:System.ValueTuple.dll'. Choosing 'Reference:System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL' because AssemblyVersion '4.0.3.0' is greater than '4.0.2.0'.

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

8 participants