Using C# 6.0 or C# 7.0 with MVC 5

The version of C# that your solution or project employs is fairly abstracted. It's not very obvious what features are or are not supported unless you try something and see red squiggles from Intellisense. Generally speaking, the C# version is based on the compiler version being used by Visual Studio and as a result, there's pretty much a 1-1 correlation between your version of Visual Studio and your version of C#. Newer versions of Visual Studio ship with newer compilers. However, after updating recently to Visual Studio 2017, I noticed that even though I could use all the latest and greatest C# features in most places in my MVC 5 projects, my views still only supported C# 5.0.

The problem is that Razor views are compiled at runtime, and runtime compilation is handled by CodeDOM providers. The one utilized by MVC 5 supports only C# 5.0. However, you can install the CodeDOM Providers for .NET Compiler Platform ("Roslyn") nuget package, to add support for the latest C# features (among other improvements).

In the Package Manager Console, run:

PM> Install-Package Microsoft.CodeDom.Providers.DotNetCompilerPlatform

Or, you can search for it in the Nuget Package Manager GUI.

Great! Now, all the fancy new C# 6.0 and C# 7.0 features work in Razor views. If you had views open in your editor, you may need to close and reopen them before the red squiggles go away, though. But wait, we're not quite done, yet.

After I did this, suddenly my project started failing builds. What the bleeding heck? To add insult to injury, the build errors were very cryptic, and didn't point to any particular piece of code. Even those that did link me to code, pointed me to whitespace, as if it had no idea where the actual issue was. After more cursing than I'd care to admit, I eventually stumbled on the problem.

The Microsoft.CodeDom.Providers.DotNetCompilerPlatform nuget has a dependency on Microsoft.Net.Compilers (>= 1.3.2) when you're building against .NET 4.5, and since Nuget is awesome, it did the very least it had to and installed version 1.3.2. Once Microsoft.Net.Compilers is installed in your project, the compiler from the package is used rather than the one in Visual Studio, and guess what? That particular version only supports C# 5.0. Ironically, I had reversed my previous issue, where now the latest C# was available in my views, but no longer in my other code. Thankfully, this one's an easy fix. Just manually upgrade to the latest version of that package (2.0.1 at the time of writing).

PM> Upgrade-Package Microsoft.Net.Compilers

After that, everything worked fine. For what it's worth, if you're building against .NET 4.6, this won't be an issue, as 2.0.1 is the minimum for the dependency then.

UPDATE 05/01/2017

Ran into another issue using C# 7.0-specific features in my Razor views. When you install the Microsoft.CodeDom.Providers.DotNetCompilerPlatform nuget, it alters you Web.config adding the following lines:

<system.codedom>  
  <compilers>
    <compiler language="c#;cs;csharp"
              extension=".cs"
              type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
              warningLevel="4"
              compilerOptions="/langversion:6 /nowarn:1659;1699;1701" />
    <compiler language="vb;vbs;visualbasic;vbscript"
              extension=".vb"
              type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
              warningLevel="4"
              compilerOptions="/langversion:14 /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+" />
  </compilers>
</system.codedom>  

Notice that langversion portion of the compilerOptions attribute? It's set to 6 by default. Change that to 7 (and 15 on the VB line, for the latest VB), and you should be good to go. Again, you'll likely need to close and reopen any Razor views currently open in your editor for the changes to take effect.

comments powered by Disqus