Skip to content

Referencing netstandard1.6 package in .NET 4.6.1 #730

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

Closed
kierenj opened this issue Jul 5, 2017 · 29 comments
Closed

Referencing netstandard1.6 package in .NET 4.6.1 #730

kierenj opened this issue Jul 5, 2017 · 29 comments

Comments

@kierenj
Copy link

kierenj commented Jul 5, 2017

This issue is about a reference resolution/loading error. It seemed to me that it's not cli related because I'm not using the .NET Core tools, not corefx related because it doesn't relate to a particular API, and not coreclr because that seems too low-level.. but I'm not sure so please educate me if I'm in the wrong place - thanks :)

dotnet version 1.2.0-beta-001297-00
VS 2017 version 15.3.0 preview 3.0 (i.e. has .NET Standard 2.0 tooling)

I have (maintain, build, publish) a NuGet package which targets only netstandard1.6.

I have a .NET 4.6.1 web application which references it.

I get the IIS error:

Could not load file or assembly 'System.Runtime, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

The NuGet package's deps.json file lists only System.Runtime 4.3, no references to 4.1. However, the assembly itself does reference 4.1.0.0 (checking via ILSpy). I don't know why - the project file is straightforward, targets just netstandard1.6, some 1.1.1 versions of Microsoft.AspNetCore.* and Microsoft.Extensions.Options packages and doesn't have any other magic. It does however reference 3 other NuGet packages in my little system.

One of those NuGet package projects also targets netstandard1.6 but also net451 (and conditionally uses the Microsoft.TargetingPack.NETFramework.v4.5.1 for the net451 build). The net451 build also conditionally has an (unversioned) reference to System.Runtime (not a package or project reference). I have no idea if this is relevant, however.

I'd just like to know what the recommended approach or next steps for tracking down the problem here would be - or how can I educate myself about this further? I get the concept of .NET Standard as an "interface", but don't grasp the entire bigger ecosystem picture in terms of these additional references. Other (.NET Core) consumers of the main NuGet package work just fine.

(note: as per dotnet/standard#295, I do have a reference to NETStandard.Library 1.6.1 on my net461 consumer project)

@Petermarcu
Copy link
Member

The. Net Core 2.0 sdk is what delivers the msbuild tasks that enable netstandard 2.0 to work correctly in .net framework projects. Can you try installing that?

@kierenj
Copy link
Author

kierenj commented Jul 5, 2017

I certainly can, although I'm not using .NET Core 2.0 or netstandard2.0. Will report back in a moment, thank you

@kierenj
Copy link
Author

kierenj commented Jul 5, 2017

Thanks for the suggestion, unfortunately I get the same error. Any advice around how to approach this would be very much appreciated.

Edit: there's a build error/warning I didn't see before, this is on the consuming project:

20> No way to resolve conflict between "System.Runtime, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" and "System.Runtime, Version=4.0.20.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a". Choosing "System.Runtime, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" arbitrarily.

Also:

20> Consider app.config remapping of assembly "System.Runtime, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" from Version "4.0.20.0" [C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Runtime.dll] to Version "4.1.0.0" [] to solve conflict and get rid of warning.

and:

20>C:\Program Files (x86)\Microsoft Visual Studio\Preview\Professional\MSBuild\15.0\Bin\Microsoft.Common.CurrentVersion.targets(1984,5): warning MSB3277: Found conflicts between different versions of the same dependent assembly that could not be resolved. These reference conflicts are listed in the build log when log verbosity is set to detailed.

Again, not sure if this is related. The NuGet package I'm consuming shows a System.Runtime (4.1.0.0) reference in ILSpy, which is confusing.

@Petermarcu
Copy link
Member

@ericstj

@kierenj
Copy link
Author

kierenj commented Jul 5, 2017

Ah, interesting. Targeting .netstandard1.6 on a new, blank NuGet package, with no references, it too references System.Runtime, 4.1.0.0 according to ILSpy. So I guess the issue isn't with the NuGet package, but the way I'm consuming it.. ?

Edit: so I guess I'm not understanding the 4.3.0.0 / 4.1.0.0 deal. The NuGet deps file shows 4.3 everywhere, ILSpy references shows 4.1, and in my net461 consuming project, it's had 4.3 added as a dependency (though, not a reference), presumably as a result of the nuget deps file. I could probably add an assemblyBinding redirect to 4.3, or downgrade to 4.1, but I don't understand why any of that would be necessary?

(What's more, despite the nuget package reference being there in packages.config, there's no System.Runtime reference actually showing in the References list, but there's a System.Runtime.dll in the bin folder, AssemblyVersion 4.0.20.0 and AssemblyFileVersion 4.6.1055.0. Yup - confused!)

@ericstj
Copy link
Member

ericstj commented Jul 5, 2017

NET461 used to be netstandard1.4 but the latest version of NuGet remapped that to netstandard2.0. It looks like you're using that new version of NuGet with the old packages.

The older packages (like the System.Runtime 4.3.0 package) have a mismatch when installed on .NET 4.6.1. This is because they have a version of their library for net461 that matches the version that was in the netstandard1.4 folder, but now that NuGet allows netstandard1.6 libraries to install they are broken.

We aren't shipping new versions of these packages, the intent is for folks to get the latest facades from the tooling.

Can you try the following:

  1. set <DependsOnNETStandard>true</DependsOnNETStandard> in your project and see if it fixes it.
  2. If not, then reference the latest NETStandard.Library.NETFramework package in your net461 project.

@kierenj
Copy link
Author

kierenj commented Jul 6, 2017

Adding that project property fixed that issue, thanks. This may not be the same issue, but I do now also get:

Could not load file or assembly 'System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

(via [TypeInitializationException: The type initializer for 'System.Web.Http.GlobalConfiguration' threw an exception.])

To give some background, this was a copy-pasted version of an old project which I updated to 4.6.1/VS2017 from 4.5/VS2015.

Note that in this case, there's an assembly binding redirect:

      <dependentAssembly>
        <assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.1.1.0" newVersion="4.1.1.0" />
      </dependentAssembly>

and in packages.config:

<package id="System.Net.Http" version="4.3.0" targetFramework="net461" />

..there's also a build warning:

2> Consider app.config remapping of assembly "System.Net.Http, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" from Version "4.1.1.0" [C:\git\kierenj\some-referenced-project-here\bin\Debug\System.Net.Http.dll] to Version "4.2.0.0" [C:\Program Files (x86)\Microsoft Visual Studio\Preview\Professional\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\\net461\ref\System.Net.Http.dll] to solve conflict and get rid of warning.

(edit: if I set the redirect to 4.2.0.0, I get Could not find a part of the path 'C:\git\kierenj\my\project\here\bin\roslyn\csc.exe'. from IIS. Wow!)

The other project (in some-referenced-project-here) is .NET 4.5.1 and has no nuget references, but does reference System.Net.Http 4.1.1.0.

And finally, the reference (on the main project) has a yellow warning icon in VS.

@kierenj
Copy link
Author

kierenj commented Jul 6, 2017

On this new one, is it this - https://github.com/dotnet/corefx/issues/9846 - that I'm hitting? I'm not sure what the appropriate workaround would be if so, can anyone advise please?

@kierenj
Copy link
Author

kierenj commented Jul 7, 2017

@ericstj please forgive me for being forward, but this is blocking me for a big new project and has eaten a fair amount of my time. I realise there's no SLA or anything here, but if you are able to recommend any course of action at all - even something time-consuming - I'd be very grateful indeed.

@Petermarcu
Copy link
Member

@ericstj isn't available right now. @terrajobst or @weshaggard may have some insight to give before @ericstj is back online.

I know System.net.http has been a challenge.

@kierenj
Copy link
Author

kierenj commented Jul 7, 2017

Thanks, since then I've had the idea to recreate the project from scratch (since it was initially a copy-paste job into VS2017, then I updated VS2017, then fiddled with the above), so I'm trying that in the meantime.

@kierenj
Copy link
Author

kierenj commented Jul 7, 2017

I've been rebuilding the project from scratch. Still a very similar mix of problems. I've added the project property and the NETStandard.Library.NETFramework package.

I added a binding redirect for Http, which solved that error this time (no roslyn compiler issue) - but am finally left with the System.Runtime error again, I then double-clicked the build warning around multiple reference version conflicts, which introduced a manifest-not-matching assembly exception for System.ComponentModel.Annotations. There are still several references in the References solution explorer node under the project with yellow exclamation errors (and the associated warnings are simply that the referenced component was not found).

Do let me know if there's anything else I can try / do to diagnose or assist.

@Petermarcu
Copy link
Member

@dsplaisted also in case he has any ideas.

@kierenj
Copy link
Author

kierenj commented Jul 10, 2017

I've now made all of the nuget packages under my control target net451 too (as well as netstandard1.6). I get the same error - currently Could not load file or assembly 'System.ComponentModel.Annotations' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040), with Calling assembly : (Unknown). with a stack trace including System.Web.Configuration.CompilationSection.LoadAllAssembliesFromAppDomainBinDirectory().

In my scenario, will referencing a net451-and-netstandard16 package result in net451 being picked?

What else can I try? I figured this would fix it! Thanks again.

@kierenj
Copy link
Author

kierenj commented Jul 10, 2017

Sorry for the comment spam. It's moved on and I can be more specific:

I'm using Windsor for DI in the .NET project and it's reflecting over the NuGet package's classes.

System.Reflection.RuntimeAssembly.GetExportedTypes(RuntimeAssembly assembly, ObjectHandleOnStack retTypes) +0 in the stack trace is throwing Could not load file or assembly 'System.ComponentModel.Annotations, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040).

As I say, the NuGet package now targets both net451 and netstandard1.6. The consuming project is .NET 4.6.1, and references System.ComponentModel (as well as .Primitives and .TypeConverter) package version 4.3.0. Via VS build warnings, there are redirects as follows:

<assemblyIdentity name="System.ComponentModel" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
	<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
</dependentAssembly>
<dependentAssembly>
	<assemblyIdentity name="System.ComponentModel.TypeConverter" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
	<bindingRedirect oldVersion="0.0.0.0-4.1.2.0" newVersion="4.1.2.0" />
</dependentAssembly>
<dependentAssembly>
	<assemblyIdentity name="System.ComponentModel.Primitives" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
	<bindingRedirect oldVersion="0.0.0.0-4.1.2.0" newVersion="4.1.2.0" />
</dependentAssembly>

The nuget package, when targeting netstandard1.6, has no specific references in this area. For net451, there's a <Reference Include="System.ComponentModel" /> which comes into play.

If I keep the bindingRedirect to 4.1.0.0 as the other outstanding VS build warning suggests, there's a runtime exception that the assembly version manifest didn't match. The version in the bin folder is 4.0.10.0. If I add a bindingRedirect to 4.0.10.0, I get:

[BadImageFormatException: Could not load file or assembly 'System.ComponentModel.Annotations' or one of its dependencies. Reference assemblies should not be loaded for execution. They can only be loaded in the Reflection-only loader context. (Exception from HRESULT: 0x80131058)]

@weshaggard
Copy link
Member

@kierenj there is a lot of issues called out in this thread so it is kind of hard to follow. Can you post a sample project demonstrating your issue somewhere and I will help diagnose it and get to the bottom of the issue.

@kierenj
Copy link
Author

kierenj commented Jul 10, 2017

@weshaggard thanks, I'd like to help get to the bottom of this. It's tricky because the code is confidential. I guess a repro would involve creating two solutions and publishing a public NuGet package from one, setting up the same references in the other. It might take me a while to find the time for that, but of course I understand the value of it.

The only issue I'm currently experiencing is the final one, which I think is described entirely by my previous comment. While I see if I can get a repro together, is there nothing in there that might be a clue?

@weshaggard
Copy link
Member

There are a lot of moving parts so it is hard to say what the real issue is just from your description.

[BadImageFormatException: Could not load file or assembly 'System.ComponentModel.Annotations' or one of its dependencies. Reference assemblies should not be loaded for execution. They can only be loaded in the Reflection-only loader context. (Exception from HRESULT: 0x80131058)

That to me says you are deploying the wrong version of this library. It looks like it is deploying the reference assembly instead of the implementation assembly. That assembly should not even need to be deployed as it ships inbox on .NET Framework. If I were to guess the issue with System.ComponentModel.Annotations has nothing to do with the other System.ComponentModel.* assemblies as it is pretty isolated from them.

As I say, the NuGet package now targets both net451 and netstandard1.6.

You seem to be consuming a locally built nuget package does this issue still occur if you directly consume the binary?

If you can get a repro that you can share with your scenario then I can hunt this down but right now I'm still at a loss as to how to help because there are too many moving pieces.

@kierenj
Copy link
Author

kierenj commented Jul 10, 2017

Ok I understand, thanks. The package is not locally built, it's built on travis-ci (linux/.net core/mono) and pushed to a private MyGet feed. Looking in the nuget package and nuspec, neither target directly references System.ComponentModel at all, there's no mention of it and no binaries in the package. (Only) the netstandard16 dll itself references System.ComponentModel 4.1.0.0. I don't understand why but the repro may help with that.

I was going to give up on .NET Standard stuff with this multi-targeting, but VS keeps using the netstandard16 version and not the net45 binary. If I can beg one more question while I get a repro together - is there anyway to override/stop that behaviour? A precedence to target selection? Any docs for that? Just trying to kick my project off before I get medieval on the repro :)

@kierenj
Copy link
Author

kierenj commented Jul 11, 2017

Yipee, I found a fairly minimal-case repro!

https://github.com/kierenj/dotnet-core-issue-730-repro

The folder structure is a little funky - I created a solution called whatever.sln and of course that created a subfolder called whatever.sln. Either way, the case should be solid.

A breakdown:

  1. NuGet package, targeting netstandard1.6
  2. References <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.2" /> and uses RequiredAttribute (via using System.ComponentModel.DataAnnotations;)
  3. This causes the assembly to reference System.ComponentModel.Annotations 4.1.0.0
  4. NuGet package then published, and referenced by a .NET 4.6.1 project (MVC / Web API if that makes any difference)
  5. Using reflection to get type/attribute info causes a TypeLoadException, that System.ComponentModel.Annotations cannot be found

Exception thrown at https://github.com/kierenj/dotnet-core-issue-730-repro/blob/master/consumer/consumer/ConsumerWeb/Controllers/HomeController.cs#L19

The repro repo doesn't have a gitignore, in case looking at the packages folder would be useful. Each commit documents the process, the errors I encountered on the way.

https://github.com/kierenj/dotnet-core-issue-730-repro/commits/master

@weshaggard
Copy link
Member

In your web project install the "System.ComponentModel.Annotations" "4.3.0" nuget package, which should automatically cause your web.config to update to add the following binding redirect.

      <dependentAssembly>
        <assemblyIdentity name="System.ComponentModel.Annotations" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.1.1.0" newVersion="4.1.1.0" />
      </dependentAssembly>

And also cause System.ComponentModel.Annotations.dll to be copied to your bin folder. Once that happens your web project works.

Let me know if that didn't fix your main project.

@kierenj
Copy link
Author

kierenj commented Jul 12, 2017

Thanks, that fixed it! I'm unblocked and very happy, gives me a couple of days to pull a demo together for our client on Friday. :)
Should either the tooling or me have added that as an explicit dependency to the nuget project?

@weshaggard
Copy link
Member

Should either the tooling or me have added that as an explicit dependency to the nuget project?

I think somewhere along the lines when if you installed the nuget packages via the UI it should have pulled this dependency, if you manually edited the packages.config file that might be why it didn't show up.

Future tooling will help flow these dependencies better. If you are able to it would be good to switch away from packages.config based projects and instead use the newer PackageReference items and that will help flow these dependent packages.

I'm going to close this issue now but feel free to ask further questions.

@kierenj
Copy link
Author

kierenj commented Jul 12, 2017

Thanks. Just to make sure we're not missing a bug - I didn't edit packages.config, I used the VS2017 UI.
It's also a .NET 4.6.1 consuming project - not .NET standard/dotnet tooling.
With that in mind, should it have happened automatically?

@weshaggard
Copy link
Member

Honestly I'm not entirely sure.

@emgarten any ideas why System.ComponentModel.Annotations package isn't correctly installed when installing https://www.nuget.org/packages/Repro110717.MainPackage/ into a net461 packages.config based project? It is in the package closure from https://www.nuget.org/packages/Microsoft.AspNetCore.Mvc.DataAnnotations/1.1.2. Perhaps there is some issue around the install picking the net451 dependencies instead of the netstandard1.6 dependencies but later we pick up the netstandard1.6 asset which is then missing this dependency.

@Alex-DE-74
Copy link

HERE IS ONE SOLUTION:
If you get this message (like many other weird messages something can't be loaded or not found) during debugging in Visual Studio, so restart Visual Studio with Administrator privilegies - message will be gone. So it must be a bug somewhere.

@spottedmahn
Copy link

Setting <DependsOnNETStandard>true</DependsOnNETStandard> on my project fixed my problem! Thanks @ericstj!

VS Error List (a warning entry)

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.

From Detailed MS build Log:

There was a conflict between "System.Net.Http, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" and "System.Net.Http, Version=4.1.1.2, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
    "System.Net.Http, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" was chosen because it was primary and "System.Net.Http, Version=4.1.1.2, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" was not.
    References which depend on "System.Net.Http, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" [C:\Users\mdepouw\.nuget\packages\system.net.http\4.3.1\ref\net46\System.Net.Http.dll].
        C:\Users\mdepouw\.nuget\packages\system.net.http\4.3.1\ref\net46\System.Net.Http.dll
          Project file item includes which caused reference "C:\Users\mdepouw\.nuget\packages\system.net.http\4.3.1\ref\net46\System.Net.Http.dll".
            System.Net.Http
    References which depend on "System.Net.Http, Version=4.1.1.2, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" [C:\Users\mdepouw\Source\Repos\MyProject\MyProject.Services.Common\bin\x64\Debug\System.Net.Http.dll].
        C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.applicationinsights.aspnetcore\2.1.1\lib\net451\Microsoft.ApplicationInsights.AspNetCore.dll
          Project file item includes which caused reference "C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.applicationinsights.aspnetcore\2.1.1\lib\net451\Microsoft.ApplicationInsights.AspNetCore.dll".
          ... more dlls that reference 4.1.1.2

I am curious though... I don't understand the part that tells me which "References" depend upon System.Net.Http, Version=4.1.1.0 from the build log. I'm reading it as it depends upon itself. What am I misunderstanding?

@Spongman
Copy link

i'm seeing this error in a 4.7.2 project.

[BadImageFormatException: Could not load file or assembly 'System.ComponentModel.Annotations' or one of its dependencies. Reference assemblies should not be loaded for execution.  They can only be loaded in the Reflection-only loader context. (Exception from HRESULT: 0x80131058)]

@karelz
Copy link
Member

karelz commented Oct 22, 2018

@Spongman it seems you are trying to load reference assembly at runtime. Reference assemblies contain only shape of types, but not code, that's why it fails.
Usually this is a result of some forceful copying of reference assemblies into project output.
Best option is to stop doing that.
If you think it is a bug in tooling, please create simple repro steps (ideally starting from new project) and we can route it further. Please create a new issue in such case. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants