Tuesday, July 8, 2014

Using RazorEngine with layouts outside of ASP.NET MVC app

RazorEngine is library that give us possibility to use Microsoft Razor library outside of ASP.NET MVC. For us it was a great way how to implement email layouts - there are even whole libraries for that if you don’t want to reimplement the wheel (e.g. ActionMailer).

If you decide to use RazorEngine for something more complex that a single view rendering, first bump on the road will probably be layout resolving. It is quite obvious, that RazorEngine supports layouts since TemplateBase class (from which your views should inherit) contains a Layout property. But a naive approach usually ends in a NullReferenceException trap (as can be seen in this issue).

The thing that got me back on track realizing that this is not a bug in library was this blogpost. I have reproduced the steps in there and then dug deeper in the source code of the library to find out, what went wrong in the first place.

First it is important to realize that RazorEngine is just a way how to compile a view. It is not a full featured view engine that is be capable of resolving layouts from files for us (when layout is specified). When you ask RazorEngine to work with a view, it compiles it and saves it in the local cache (defined as a ConcurrentDictionary in TemplateService). If the view is linked to other views (layouts, partial views...) it just looks for the views in the cache by their name. Thus the only thing, that you need to do when creating a view with a layout is compiling the layout before the view and then linking the layout from the view by the same name as is the cache key.

Let me show you an example. First you need to install RazorEngine package from NuGet.

var layout = "<html><head><title>Page with layout</title></head><body>@RenderBody()</body></html>";
var content = "@{ Layout = \"Layout\"; } content string";

Razor.Compile(layout, "Layout");
var resultView = Razor.Parse(content);

And the result saved in the result variable is

<html><head><title>Page with layout</title></head><body> <span>content string</span></body></html>

The important thing here is - you have to compile the layout before compiling/parsing the view. Also the name, that you pass as a second parameter of the Razor.Compile method must be the same as a Layout name mentioned in the view (in this example it was "Layout"). If you don’t play by these rules, you’ll get NullReferenceException (or more meaningful exception thanks to my accepted pull request).

9 comments:

  1. Replies
    1. I have read your blog its very attractive and impressive. I like it your blog.

      Dot Net Training in Chennai Dot Net Training in Chennai .Net Online Training .Net Online Training Dot Net Training in Chennai Dot Net Training in Chennai


      Dot Net Online Training Dot Net Online Training LINQ Online Training LINQ Online Training ASP.NET Online Training ASP.NET Online Training

      Delete
  2. Thank you for taking the time to provide us with your valuable information. We strive to provide our candidates with excellent care and we take your comments to heart.As always, we appreciate your confidence and trust in us.

    SAP training in Chennai

    ReplyDelete
  3. Great article. Glad to find your blog. Thanks for sharing.

    web designing training in chennai

    ReplyDelete
  4. Great Information,it has lot for stuff which is informative.I will share the post with my friends.
    Case Study Writing Services

    ReplyDelete
  5. MARKETING CASE STUDY HELP & MARKETING HELP Marketing Case Study Help Opportunity to all student and different researchers. please feel free to visit Marketing Help Case Study

    ReplyDelete
  6. Get your Finance Assignment Help, Homework, Project Help Online for Students in UK, USA, and Australia by Professional finance writers at affordable prices. Finance Assignments Help

    ReplyDelete