15

I've looked for other questions related to this, but none seem to be quite what I'm looking for.

I have a website running on ASP.NET Core with the new project structure in VS2017. Code files using C#7 features compile fine. But attempting to use those features in a View results in a series of errors about syntax. I tried installing Roslyn to get it to be used when compiling views since from what I can tell the C#7 features are available in the Roslyn nuget package 2.x and higher. But now I'm getting feedback that explicitly says

error CS8059: Feature 'out variable declaration' is not available in C# 6. Please use language version 7 or greater.

In the past I'd check the web.config, but there is no web.config in an ASP.NET Core project other than the nearly empty one at the root for handling the request off from IIS.

How do I indicate that my Views should be compiled with Roslyn since that isn't done until runtime? At least I'm assuming that would fix my problem at this point.

Edit: That question is not a duplicate of this, as I mentioned at the start, I've also looked for existing questions. That's specifically enabling C#7 features in your app at compile time, and only for an ASP.NET application. I'm using ASP.NET Core, which does not have a web.config with any compilation settings defined in it. Also, what I'm trying to do it for the Views which are compiled at runtime and may be on a different system.

Solution:

For anyone interested, You have to add Roslyn to your project (which I knew), but you also have to configure the RazorViewEngineOptions to use CSharpParseOptions that indicate the language version (default is 6). I had done this but I didn't do it correctly. I needed to assign the result of WithLanguageVersion() back overtop of the ParseOptions to replace them.

services.AddMvc().AddRazorOptions(options => options.ParseOptions = options.ParseOptions.WithLanguageVersion(LanguageVersion.CSharp7));
Stephen Kennedy
  • 20,585
  • 22
  • 95
  • 108
Nick Albrecht
  • 16,607
  • 10
  • 66
  • 101
  • Not a duplicate, added details why. – Nick Albrecht Mar 16 '17 at 21:58
  • The error message you get indicates that the compiler was properly upgraded (the new syntax was recognized). There must be a /langversion setting somewhere that controls this in ASP.Net Core, but I don't know where it is. Sorry. – Julien Couvreur Mar 17 '17 at 23:17
  • Yeah that's where I'm kind of stuck too. All of the files holding configuration details related to compilation, that I'm aware of, don't get published during deployment. So I'm not sure where I would even put a setting to tell it to enable C# 7 features at runtime compilation. – Nick Albrecht Mar 18 '17 at 03:31

2 Answers2

16

Could you try the following (recommended by folks on the ASP.NET core team):

  1. Install the Microsoft.CodeAnalysis.CSharp (version 2.0.0) and System.ValueTuple (version 4.3.0) packages
  2. In Startup.cs, in the ConfigureServices method, configure Razor to use C# 7 by doing the following:

    services.AddMvc().AddRazorOptions(options =>
         options.ParseOptions = new CSharpParseOptions(LanguageVersion.CSharp7));
    
recursive
  • 83,943
  • 34
  • 151
  • 241
Julien Couvreur
  • 4,473
  • 1
  • 30
  • 40
  • I already had all that, but I tried it again to double-check to be sure, and yours worked. After looking for discrepancies, I discovered that your assignment to `ParseOptions` works but my call to `ParseOptions.WithLanguageVersion()` did not. So I went looking for the implementation (I LOVE that this is all open source). Turns out `WithLanguageVersion()` does not modify your existing `ParseOptions` at all, but instead returns a new `CSharpParseOptions`. So once I assigned that back to the `ParseOptions` property, it works fine. A little counter intuitive, but it works. :-) – Nick Albrecht Mar 22 '17 at 17:44
  • Thanks a bunch for the help!! :-) – Nick Albrecht Mar 22 '17 at 17:52
  • Will this work for named tuples too? I'm under the impression it won't, certainly from the tests I've ran it seems to be the case as it throws a `RuntimeBinderException`. – Joseph Woodward Apr 13 '17 at 12:10
  • @JosephWoodward I'm not aware of any tuple scenarios that could throw a `RuntimeBinderException`. That exception is typically related to uses of `dynamic`. Please create a github issue on roslyn if you can confirm your repro/problem. – Julien Couvreur Apr 22 '17 at 01:14
  • 2
    A note: This is currently broken in Microsoft.CodeAnalysis.CSharp v2.3.0/2.3.1 ([GitHub issue](https://github.com/dotnet/roslyn/issues/20873)). The workaround is to use v2.2.0. – vaindil Aug 09 '17 at 18:21
  • Microsoft.CodeAnalysis.CSharp v2.4.0 has fixed the problem with 2.3.x as per above GitHub issue. However, for me Visual Studio 15.4.4 editor is no longer (was OK in 15.3.3) able to parse a model with a value tuple, although once run it is fine. – Leo Hendry Nov 17 '17 at 15:10
1

So I found out that there are some compilation options exposed that you call call in the ConfigureServices() call.

public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services.AddMvc().AddRazorOptions(x => x.ParseOptions.WithLanguageVersion(LanguageVersion.CSharp7));
}

Problem is LanguageVersion.CSharp7 gives an error if you don't add Roslyn. So I'm assuming that is necessary.

After adding Roslyn, everything compiles fine, BUT the view still gives an error.

@{
    //My view code
    string s = "1";
    int.TryParse(s, out int i);
}

So if MVC exposes a RazorOptions that you can use to specify the language version, why is it not honored?

Nick Albrecht
  • 16,607
  • 10
  • 66
  • 101
  • You need to use `services.AddMvc().AddRazorOptions(x => x.ParseOptions = x.ParseOptions.WithLanguageVersion(LanguageVersion.CSharp7));` because you're dealing with the immutable roslyn here :) – Suchiman Jun 03 '17 at 22:44