Razor views pre-compilation with ASP.NET 5 and MVC 6

In previous versions of MVC framework, running on top of the “classic” ASP.NET runtime, it was quite common for developers to switch view compilation on, so that the views get compiled upfront, allowing you to see any errors at compile time, rather than at runtime.

This was done by a simply adding <MvcBuildViews>true</MvcBuildViews> to your csproj file.

Given that everything changes in the new ASP.NET 5 world, how would you do it now? Let’s explore.

Introducing ICompileModule

KRuntime contains an assembly neutral ICompileModule which can be used for various meta-programming purposes. It allows you to process the Roslyn’s CSharpCompilation object prior to the compilation being emitted (but after the compilation object was created), as well as access to the assembly and PDB/MDB symbol afterwards. Additionally, it gives you insight to the Roslyn emitted diagnostics.

You can use ICompileModule for a bunch of purposes, mainly to customize the way the compilation should happen.

How do you register modules then? Well you don’t. The Roslyn compiler, or rather the ASP.NET 5 worker class that wraps the Roslyn compiler and is responsible for creating the compilation (also processing Assembly Neutral Interfaces etc), will simply find all ICompileModule that exist within the source files that are subject to compilation, and apply them.


Using a custom ICompileModule, ASP.NET MVC 6 can provide the capability of building views. You don’t even have to implement it on your own, because it’s already there – it’s called RazorPreCompileModule.

The class is abstract so you will just have to inherit from it, and put it somehwere in the code. Plus, as already mentioned, in order fot ICompileModule to kick in, you have to have it declared somehwere in your code anyway.

For example:

RazorPreCompileModule will internally use RazorPreCompiler class, which will use – surprise – Roslyn, to generate syntax trees for your views and include them in the Roslyn’s compilation object, which will later be emitted, as well as throw into the context object any diagnostics it produces, so that those can be picked up by your design time host.

Actually, all methods on RazorPreCompiler, as well as on RazorPreCompileModule are virtual so it’s very easy to extend the logic or throw in your own custom syntax trees should you ever need to do so (perhaps expand your own custom placeholders into code etc).

Trying it out

Note: This functionality does not work correctly in 1.0.0-beta1, which is the version used by Visual Studio 2015 preview! This means, you will have to use nightly builds to try it out right now, or wait for the next milestone release. Here’s a good wiki article explaining how to get started with nightlies.

Let’s consider the following simple example:

A model with a controller:

And a view:

You can immediately see that this should fail, as we are asssuming Model.AccountStatus is bool, whereas it’s actually an enum. However, since it’s in Razor, this code will compile and you would only see the problem at runtime.

However, the moment you put in the the custom EnforceRazorViewCompilation we just defined moments ago in your code, you will see the build fail as expected:

Screenshot 2014-12-12 11.07.17

In this case I’m seeing the error, as it’s from the Desktop CLR and Core CLR.

Be Sociable, Share!

  • Pingback: Dew Drop – December 12, 2014 (#1914) | Morning Dew()

  • Pingback: The Morning Brew - Chris Alcock » The Morning Brew #1758()

  • Pingback: Dew Drop – December 15, 2014 (#1915) | Morning Dew()

  • clement_911

    Can we still use https://razorengine.codeplex.com/ with asp.net 5?

    • Me

      I don’t know!

    • InversionOfControl

      I believe a newer version of RazorEngine is in the works to take advantage of Razor4+Roslyn

  • Pingback: Les liens de la semaine – Édition #111 | French Coding()

  • Rick Strahl

    Nice detective work Filip.

    But – this seems like a crazy way to ‘configure’ behavior. Subclass an existing interface, that the compiler has to search out to find??? That’s pretty whacky if you ask me. I realize there’s more that you can do with this but settings like this that need to be turned on and off frequently and they need a non-code way to be configured, or at the very least a simple discoverable switch on a top level configuration object (like MvcOptions).

  • Pingback: Links of the month (December Edition) | Jan @ Development()

  • Rolando Puno

    I wanted to have that razor engine has their own complete controls..

  • http://m0sa.net/ m0sa

    I don’t know if this was always the case, but you have to put the ICompileModule implementations inside the ./compiler/preprocess folder, or the KRE/XRE won’t invoke it at build time.

    • Richard

      When creating a new ASP.NET 5 project with Visual Studio, the file was already there in ./compiler/preprocess folder. Just needed to uncomment the code.

  • http://rehansaeed.co.uk Muhammad Rehan Saeed

    I am using Beta 4 now, so why is this not turned on by default? Should it be turned off for the Development environment? If so, how?