StackExchange / StackExchange.Precompilation

Roslyn based csc.exe and aspnet_compiler.exe replacement with metaprogramming hooks for ASP.NET MVC projects from the pre-DNX era
MIT License
155 stars 37 forks source link

Intellisense errors in views #31

Closed natehitze closed 7 years ago

natehitze commented 7 years ago

Intellisense in views reports that C# 7 features can't be used in C# 5. Is there an easy way to fix this? I tried opening the sample view in this project in VS2017 safe mode and I get the same error.

image

m0sa commented 7 years ago

That's Visual Studio. The editor launches an out of process compilation, that honors web.config and still uses system.codedom/compilers section. You can work around that by installing the Microsoft.CodeDom.Providers.DotNetCompilerPlatform package, and setting the language version, even though you wouldn't be using it, if you're replacing the view engines.

More details here

natehitze commented 7 years ago

Thanks. I did some digging and found the following:

Good news: Just having compilerOptions="/langversion: 7" made Intellisense (and ReSharper) happy. It doesn't matter what compiler type you set -- even if you use nonsense for the type name. The web.config Intellisense does care if you make up a name though, so I used the default provider, Microsoft.CSharp.CSharpCodeProvider.

Bad news: When I run Test.WebApp, I get a YSOD with error: CS1617: Invalid option '7' for /langversion; must be ISO-1, ISO-2, 3, 4, 5 or Default. This occurs even when I'm only using the PrecompiledViewEngine.

Any idea why the compiler is still being run?

natehitze commented 7 years ago

Found it. The compiler is being invoked at app start for global.asax.

m0sa commented 7 years ago

Yeah, you should be able to work around it if you implement the stuff that gets generated from global.asax in C#.

Some relevant links:

m0sa commented 7 years ago

OK, I dug around a bit further. If you delete the global.asax file, the runtime still needs to know which (custom) HttpApplication to use. Fortunately the BuildManager falls back to PageParser.DefaultApplicationBaseType if the file can't be compiled (or is not found), which can be specified before the app is initialized / via a PreApplicationStartMethodAttribute.

So this seems to work (allowing you to specify /langversion:7 even without the roslyn CodeDOM provider)


// in AssemlbyInfo.cs
[assembly: PreApplicationStartMethod(typeof(Initializer), nameof(Initializer.PreApplicationStart))]

// in Initializer.cs
public static class Initializer
{
    public static void PreApplicationStart() =>
        PageParser.DefaultApplicationBaseType = typeof(CustomApplication);
}
natehitze commented 7 years ago

Thank you!! Your workaround is working perfectly for us.