ASP.NET MVC4 Gotcha: Embedded Views and Razor Pre-Compilation
In the course of some of our work on MarkedUp, we discovered an interesting gotcha with MVC4, embedded views, and ASP.NET pre-compilation.
A little back-story:
One of the things we did as part of a major refactoring recently was to pull all of our email templates out of the main MarkedUp MVC4 project and stick them into their own independent assembly – we did this because we anticipated that these templates would have to be shared across multiple web distinct web applications running behind our firewall.
We use ActionMailer to generate our text and HTML emails from Razor templates, and one of the things that broke with MVC4 is the RazorEngine project which was used by ActionMailer.StandAlone to parse Razor templates in non-MVC4 assemblies.
So, what we did in this instance was embed our Razor views directly into the child assembly and wrote our own VirtualPathProvider to serve them from the MVC4 application – a standard practice for handling this sort of thing.
We started running our staging and development versions of our app this way without thinking twice about it.
Eventually, when we wanted to speed up our staging server’s rendering performance on AppHarbor we enabled ASP.NET pre-compilation. And since it was just our staging server with just us on it, no one noticed that our email volume dropped to zero.
Until we started bringing aboard a small number of friends to help us test our service, which is when we noticed the error.
When you turn on ASP.NET Pre-Compilation, the underlying virtual path changes and will change the behavior of your custom VirtualPathProviders.
Hence, our custom VirtualPathProvider was no longer able to find our embedded views. Doh!