Thursday, 3 October 2013

Executing Razor Views outside of a web application with NonHttpRunTimeRazorSupport

NonHttpRunTimeRazorSupport (catchy) is a small library that allows you to use ASP.Net MVC Razor views to render content outside of the context of a running ASP.Net application  with full support for Layouts, _ViewStart inclusion, Partials, built-in HtmlHelpers etc.


Razor views are a really nice mechanism for generating web page content within an ASP.Net MVC application. They're so great in fact, that it's a shame to use them just to render HTML to display in a browser. What if we could use them to generate other content within our application, like email messages?

Many applications need to send emails. For something simple, like a one-off message to a site administrator, you might be able to get away with using a StringBuilder to generate the content of the email. If you need to send a range of rich HTML emails and want developers to be able to modify them easily, a full-blown template system like Razor is a much more flexible and maintainable mechanism.

Another common requirement is to send emails in an "offline" scenario. By "offline", I mean outside of the context of an HTTP request in a running ASP.Net application. Maybe you want to send emails within a console app, Windows service or an NServiceBus / MassTransit / Rebus message handler.

NonHttpRunTimeRazorSupport lets you use all of Razor's features outside of a running web app.

There are loads of other things you could use this library for - but email is probably one of the most common requirements it supports.

How it Works

The library is on GitHub at If you know about git, go ahead and clone the repo on your development machine, otherwise you can download a zip file of the source or browse the code directly on GitHub.

This solution uses RazorGenerator, a great tool that allows you to pre-compile Razor views at design time. As you edit your Razor views in Visual Studio, a pre-compiled view (an accompanying C# class file a bit like a web forms Something.aspx.Designer.cs file). Pre-compiled views can be used instead of .cshtml files that are compiled on-the-fly by RazorViewEngine. One thing that the RazorGenerator project is missing is an example of how to render pre-compiled Razor views in the "offline" context we introduced above*.

Razor View templates, whether compiled at design-time by RazorGenerator or at runtime by RazorViewEngine, are instances of WebViewPage. Views of this type are designed to execute in the context of an HTTP request. The standard built-in RazorViewEngine assumes a web request and other supporting infrastructure offered by HttpRuntime to be present when locating and rendering Razor views. 

The main purpose of NonHttpRunTimeRazorSupport is to work around this limitation. A customised ViewEngine and fake implementations of HttpContext (and it's HttpRequest, HttpResponse members) are used to support the execution of Razor Views.

Needless to say, you have to write your templates with this "offline" context in mind. Putting something like @HttpContext.Current.Request.ServerVariables[...] in the middle of your template would result in an exception. Note that the library attempts to provide help here by throwing an exception with an informative message if  any non-supported HttpContext (and family) members are accessed.

Getting Started

See the README for details on how to get up and running.

The repository includes a simple EmailDemo console app, that demonstrates how you might handle sending emails in your application.

The EmailNotificationService class uses Razor templates to render email content, using a convention to locate views based on the name of the model type. Here's how the views are structured:

This foundation would allow you to support a range of emails without adding a great deal of code. For each message type, you would simply need to add a model and Razor templates to render the subject, text and html body content. Here's the code for EmailNotificationService in full:

Look at EmailNotificationService.cs on github if you can't see the code in-line above.


There are other libraries that allow you to use Razor templates to generate email content, such as MvcMailer and ActionMailer, but, they don't fully support sending Razor-templated emails in an "offline" scenario ("Email sending from a background process" is still listed as an upcoming feature on the MvcMailer Wiki page and the standalone version of ActionMailer doesn't appear to support layouts and other Razor features.

What Next?

I'll consider adding a NuGet package once I've got feedback from using this approach on some other projects. Any comments or feedback would be great.

I came up with this solution while working on a project that was already using RazorGenerator. I'm interested in exploring whether it would be possible to bypass RazorGenerator and compile the views on the fly. Compiling Razor views from templates stored in a data store could also be interesting....

Happy mailing!

* I should point out that views compiled with the RazorGenerator "Template" generator can run outside of the context of an ASP.Net application. They are not the same thing as standard MVC Razor views - the declarative Layout property, _ViewStart pages, partials, HtmlHelper / UrlHelper etc are not available.


  1. Email is one of those things that could easily be offloaded to a background service. Sadly, MvcMailer gives me access to the HttpContext which allows me to generate urls respective to my environment. Not a huge deal, but can be very helpful when you have a dev, staging, and production environment. I guess the easy solution to that is just creating app settings with the proper base url.

    1. This solution renders templates with a special implementation of HttpContext to support "offline" use, with the properties needed to support UrlHelper etc. It's pretty nice to be able to use the following in an email template rendered by a console app:

      <a href="@Url.Absolute("~/tnc")">terms and conditions</a>

      You need to supply the base URL when you render the template, e.g.:

      string content = renderer.RenderView(model, baseUri);

      I see what you're saying - rendering an email directly within a web app means that it automatically uses the right host name in URLs. Usually, a background service will have a separate deployment per environment, e.g. test and production, so the config file solution isn't too difficult.

      If you're queueing email from more than one site to be sent by a shared background service, you could include the base URL in the command / message ... whatever you're using.

      In one project scenario (multi-tenant e-commerce), a background service gets the URL for each storefront site from the database.

  2. Interesting how does this compare with Matthew Abbott's RazorEngine that is already a Nuget package ? I've tried the RazorEngine, but I'm struggling a bit to do anything more than the basics due to the lack of documentation. I will try this tool as well and see how far I can get. Thanks for your efforts !

  3. They may do not have the fundamental aptitudes expected to build up a completely custom web webpage. bahrain web development

  4. A wide range of Search Engine Optimization and Digital Marketing techniques design and develop by the top business analysis in Malaysia.
    serpmind malaysia


  5. This is genuinely an awesome read for me. I have bookmarked it and I am anticipating perusing new articles. Keep doing awesome!
    Web Development

  6. Domain hosting wiki: for bloggers, business owners and webmasters looking for starting, maintaining and knowing more about domains and hosting

  7. we need to set a relationship that produces an adequate measure of put stock in, certainty, dependability and energy.

  8. Recently checked your web development services. Your five star ratings have really impressed me. web development services