Aspnetcore: Predefined type 'System.ValueTuple is not defined or imported

Created on 6 Nov 2017  路  25Comments  路  Source: dotnet/aspnetcore

ASP.NET Core Web Application targeting .net 4.7.1 cannot use System.ValueTuple.

Repro:

  1. Create a new ASP.NET Core Web Application that targets .net 4.7.1
  2. Add a class that has a tuple
  3. Observe errors.
    -Cannot define a class or member that utilizes tuples because the compiler required type 'System.Runtime.CompilerServices.TupleElementNamesAttribute' cannot be found. Are you missing a reference?
    -Predefined type 'System.ValueTuple`2' is not defined or imported
area-infrastructure

Most helpful comment

I'm strongly against cross-compiling extensions to .NET Framework. I think we need to lean harder on the .NET Standard team to resolve this issue. If making the type issues with System.ValueTuple and net471 are truly impossible, I think .NET Standard team should update docs and tools to encourage users to target .NET 4.7.2 because anything less is not actually compatible with netstandard2.0.

I know there are important tradeoffs to weigh, but if we, as a part of the .NET team, have to cross-compile to .NET Framework to workaround this, then I think netstandard2.0 has failed deliver on one if its major promises.

All 25 comments

A workaround could be referencing the System.ValueType package.

This issue is being tracked in https://github.com/dotnet/standard/issues/567.

This issue is being tracked in dotnet/standard#567.

@pranavkm - According to that issue, there's a comment stating that package authors can workaround the issue by adding net461 as an additional target framework. Indeed, this is currently the official recommended guidance for packages that target netstandard2.0. It is desirable for the packages to workaround the issue rather than forcing app developers to require .NET Framework 4.7.2. In my case, I've encountered a similar issue because of my reference to Microsoft.AspNetCore.SignalR.Protocols.MessagePack. That package references MessagePack which references System.ValueTuple. If Microsoft.AspNetCore.SignalR.Protocols.MessagePack were updated to include net461 as a target framework, then the issue would go away.

Can you re-open this issue to apply this workaround?

For the googlers, we hit this today running ASP.NET Core on .NET Framework 4.6.2 (as a standard .NET Framework project). The problem turned out to be caused by the fact that we had added the ASP.NET Core DLLs to a library project, and hadn't added them to the executable which referenced the library. (This problem also caused any requests to time out, with no log messaged being emitted). Adding them to the executable's project as well solved the issue.

That package references MessagePack which references System.ValueTuple. If Microsoft.AspNetCore.SignalR.Protocols.MessagePack were updated to include net461 as a target framework, then the issue would go away.

cc @muratg, do you know if there's any remaining work here?

@davidfowl @halter73 do we need to workaround this for 2.2?

Is there a workaround for the app developers that we can recommend instead?

Is there a workaround for the app developers that we can recommend instead?

It looks like the workarounds for app developers are either directly referencing the System.ValueType package or upgrading to .NET Framework 4.7.2.

My understanding is that @mthalman-msft is asking for us to update our Microsoft.AspNetCore.SignalR.Protocols.MessagePack package to target net461 in addition to netstandard2.0 so app developers aren't force to use a workaround.

I'm not sure why SignalR is special though. The guidance linked to in @mthalman-msft's comment says the following:

鉁旓笍 CONSIDER adding a target for net461 when you're offering a netstandard2.0 target.

Using .NET Standard 2.0 from .NET Framework has some issues that were addressed in .NET Framework 4.7.2. You can improve the experience for developers that are still on .NET Framework 4.6.1 - 4.7.1 by offering them a binary that is built for .NET Framework 4.6.1.

Based on that guidance, it would seem that all of our packages that target netstandard2.0 should should also target net461.

I'm not sure why SignalR is special though.

Based on that guidance, it would seem that all of our packages that target netstandard2.0 should should also target net461.

The only thing special about SignalR is that it produces the issue I identified. Yes, other packages also may not be targeting net461 but I don't know for sure whether they are even capable of producing issues that are resolved by adding it as a target. So that's the difference.

It looks like fixing this would require cross-compiling netstandard2.0 targeting packages in 2.x. Would we patch something like this?

@pranavkm do we know how many of our packages are impacted? We can surely consider bringing it to the shiproom. cc @Eilon

Also, is 3.0 fine?

Presumably most of the Extensions packages n 3.0 would be problematic. For 2.x, I'm guessing nearly all of them since most packages aren't cross-compiled. However given that there is fairly trivial workaround (adding the System.Tuple package), perhaps documenting it would be the more appropriate resolution.

Yes it seems like we should do this for extensions.

@davidfowl --> do what exactly? Doc, or cross-compile?

Cross compile in 3.0

(Removing SignalR label, since this is broadly applicable)

Sad.

cc @natemcmaster

I'm strongly against cross-compiling extensions to .NET Framework. I think we need to lean harder on the .NET Standard team to resolve this issue. If making the type issues with System.ValueTuple and net471 are truly impossible, I think .NET Standard team should update docs and tools to encourage users to target .NET 4.7.2 because anything less is not actually compatible with netstandard2.0.

I know there are important tradeoffs to weigh, but if we, as a part of the .NET team, have to cross-compile to .NET Framework to workaround this, then I think netstandard2.0 has failed deliver on one if its major promises.

I'm strongly against cross-compiling extensions to .NET Framework. I think we need to lean harder on the .NET Standard team to resolve this issue. If making the type issues with System.ValueTuple and net471 are truly impossible, I think .NET Standard team should update docs and tools to encourage users to target .NET 4.7.2 because anything less is not actually compatible with netstandard2.0.

We've done that. See these docs:

鉁旓笍 CONSIDER adding a target for net461 when you're offering a netstandard2.0 target.

Using .NET Standard 2.0 from .NET Framework has some issues that were addressed in .NET Framework 4.7.2. You can improve the experience for developers that are still on .NET Framework 4.6.1 - 4.7.1 by offering them a binary that is built for .NET Framework 4.6.1.

Maybe we can make the guidance "鉁旓笍 DO" instead of "鉁旓笍 CONSIDER". That or include more information about what details package authors should consider when deciding whether or not to cross-target net461.

Saying the .NET fx has some issues that were addressed and that you can improve the experience of .NET fx developers by cross-targeting doesn't help me identify which packages that target netstandard2.0 should also target full framework net461. If it's all of them, "鉁旓笍 DO" guidance makes a lot more sense.

Maybe we can make the guidance "鉁旓笍 DO" instead of "鉁旓笍 CONSIDER"

It depends. If you're targeting .NET Standard 2.1 you don't have to :-)

The guidance is already for "when you're offering a netstandard2.0 target".

Then we're saying our packages only work on .NET Framework 4.7.2 which severely limits their usage in libraries.

To clarify - I'm not opposed to cross-compiling, on principle. I'm opposed to cross-compiling as a workaround. @davidfowl if .NET Standard 2.0 is basically guaranteed to be busted on < net472 forever and we truly care about supporting extensions packages for apps targeting < net472, then it seems our hands are tied and we have to cross-compile.

@terrajobst We've done that.

Do it more. Make it obvious. Tooling and docs say .NET Framework 4.6.1 is supported. It is misleading to tell our customers that .NET Standard 2.0 is supported on .NET Framework 4.6.1, but oh, by the way, it's basically guaranteed to break and we won't fix it so you need to update to 4.7.2 or spend some time in google to find the magic workarounds.

image

Closing because we have considered this issue and feel that the solution is worse than the workaround in most cases.

For projects targeting .NET Framework earlier than 4.7.2, additional references will need to be added to the project. Projects targeting .NET Framework 4.7.2 (or newer) or .NET Core, everything should work fine.

Was this page helpful?
0 / 5 - 0 ratings