Tuples do not work with # 7 (roslyn compiler exception)

For some time, we have been using some of the new C # 7.0 features in our razor files. We have integrated the Roslyn compiler into our web projects that currently target the .NET Framework 4.6.2.

Today I wanted to try tuples in a razor file, for example:

@functions { public (string labelName, string sfName) GetNames(PurchaseType purchaseType) { switch (purchaseType) { case PurchaseType.New: return (labelName: Booklist.New, sfName: SpecflowIdentifiers.BooklistItem.CheckBoxNew); case PurchaseType.Rental: return (labelName: Booklist.Rent, sfName: SpecflowIdentifiers.BooklistItem.CheckBoxRental); case PurchaseType.SecondHand: return (labelName: Booklist.Secondhand, sfName: SpecflowIdentifiers.BooklistItem.CheckBoxSecondHand); default: throw new ArgumentOutOfRangeException(nameof(purchaseType), @"should not get here"); } } } @helper RenderCheckbox(PurchaseType purchaseType, int index, decimal priceTo) { var names = GetNames(purchaseType); var x = name.labelName; // render something } 

The result is the following exception:

CS8137: It is not possible to define a class or member that uses tuples because it does not need to find a compiler like "System.Runtime.CompilerServices.TupleElementNamesAttribute". Are you missing a link?

CS8179: The predefined type 'System.ValueTuple`2' is not defined or not imported.

This led me to an https://stackoverflow.com/a/166908/2126 which states that I have to add the System.ValueTuple package to the project. But I already added that I added.

These are the packages used in config:

 <package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="1.0.8" targetFramework="net462" /> <package id="Microsoft.Net.Compilers" version="2.4.0" targetFramework="net462" developmentDependency="true" /> <package id="System.ValueTuple" version="4.4.0" targetFramework="net462" /> 

So, I will return to using the old Tuple<> right now. I would like to know if anyone knows what I'm missing.

Edit 11/16/2017:

So, I changed public (string labelName, string sfName) GetNames(PurchaseType purchaseType) to public ValueTuple<string, string> GetNames(PurchaseType purchaseType) and this gives me the following exception:

CS0433: The type 'ValueTuple' exists as in System.ValueTuple, Version = 4.0.2.0, Culture = neutral, PublicKeyToken = cc7b13ffcd2ddd51 and mscorlib, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089 '

And that led me to 'ValueTuple <T1, T2>' exists in both "System.ValueTuple ..." and "mscorlib ..." , giving the actual answer. I have the .NET Framework 4.7 installed, and since the razor is compiled at runtime, it just uses this version.

Regards, Rick

+5
source share
2 answers

Razor views are compiled at runtime by ASP.Net and do not automatically inherit links or other settings from your project.

You need to add System.ValueTuple to compile ASP.Net runtime in Web.config :

 <system.web> <compilation> <assemblies> <add assembly="System.ValueTuple" /> 
+6
source

This seems to be a good razor hell. If you are targeting .NET 4.7 or later, you should not reference System.ValueTuple because all the necessary types are already part of mscorlib. But it seems to me that somehow Razor uses the latest version of mscorlib, even if you specifically aimed, for example ..NET 4.6.2. Therefore, it seems to me that, at least in the system where .NET 4.7 is installed, in fact, the solution to remove

  <system.web> <compilation> <assemblies> <add assembly="System.ValueTuple, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51"/> 

Thus, you can, of course, disrupt compilation of the application at run time on servers where .NET 4.7 is missing, or precompilation if you use it.

If at least all of your servers are in the same status, you can use configuration conversions.

Also, when checking web.configs, check both the root web.config file and the web.config folder in the view folder.

If someone has a similar problem with precompilation during deployment, so far the only way I have been able to solve it was to add a link to System.ValueTuple to the CSC command line directly as follows:

 <system.codedom> <compilers> <compiler extension=".cs" compilerOptions='/langversion:7 /nowarn:1659;1699;1701 /R:"../packages\System.ValueTuple.4.4.0\lib\net461\System.ValueTuple.dll"' xdt:Locator="Match(extension)" xdt:Transform="SetAttributes" /> </compilers> </system.codedom> 

In the conversion file for server deployment. This wants to work for compilation at runtime because it does not have access to ../ packages.

0
source

Source: https://habr.com/ru/post/1273394/


All Articles