Text templating using Razor the easy way

As a web guy, I’ve slung more than my fair share of angle brackets over the tubes of the Internet. The Razor syntax quickly became my favorite way of generating those angle brackets soon after its release. But its usefulness is not limited to just the web.

The ASP.NET team designed Razor to generate HTML markup without being tightly coupled to ASP.NET. This opens up the possibility to use Razor in many other contexts other than just a web application.

For example, the help documentation for NuGet.exe is written using the Markdown format that is produced by NuGet.exe. NuGet.exe reflects over its own commands and and uses a Razor template to generate the properly formatted output.

The check-in that enabled this caught my eye and prompted me to write this blog post as it’s a very clean approach. I’ll show you how to do the same thing in no time at all.

RazorGenerator

The first step is to install the RazorGenerator extension from the Visual Studio Extension Gallery.

If you haven’t used the Extension Gallery before, within Visual Studio click on the Tools > Extension Manager menu option to launch the Extension Manager dialog. Select the Online tab and type in “RazorGenerator” (without the quotes) in the upper right search bar.

Make sure to install the one named “Razor Generator” (not to be confused with “Razor Single File Generator for MVC”).

razorgenerator-in-vs-extension-gallery

Create your application

For my sample application, I created a simple console application and added a reference to the following assemblies:

  • System.Web.WebPages.dll
  • System.Web.Helpers.dll
  • System.Web.Razor.dll

I then added a new text file and named it RazorTemplate.cshtml. You can name yours whatever you want of course.

Make sure to set the Custom Tool for the CSHTML file to be “RazorGenerator”. To do that, simply right click on the file and select the Properties menu option. Type in “RazorGenerator” (sans quotes) in the field labeled Custom Tool.

Razor-file-properties

I added the following code within the CSHTML file:

@* Generator : Template TypeVisibility : Internal *@
@functions  {
    public dynamic Model { get; set; }
}
<ul>
@foreach (var item in Model) {
    <li>@item.Name (@item.Id)</li>  
}
</ul>

That first line is a generator declaration. It’s required to by the Razor Generator. I chose to make the generated template class internal.

The next line starts a functions block. I specify a property for the template named Model in there. If you’re not a fan of the dynamic keyword, please don’t freak out. At least not yet.

I simply chose a dynamic property for the purposes of demonstration, but I could have just as easily made it a strongly typed property. Well, not just as easily as I would have had to create a another type first. But you get the idea.

In fact, I could have added multiple properties to this template if so desired. These properties and methods added here will show up in the generated template class.

The next section is simply the usual razor syntax markup you know and love which is written against the property I defined. In case you’re out of practices with Razor, be sure to check out the C# Razor Syntax Quick Reference I wrote a while back.

Render the template

Now all we need to do is instantiate the template, populate the properties we defined in the template with real values, and we’re done!

So what exactly are we instantiating? The steps we took up until now results in the Razor file generating a template class. If you expand the CSHTML file, you can see the generated class.

Razor-Generated

That’s the class we need to instantiate. Here’s some code I added in Program.cs that makes use of this generated template class.

class Program {
    static void Main(string[] args) {
        var template = new RazorTemplate {
            Model = new[] { 
                new {Name = "Scott", Id = 1},
                new {Name = "Steve", Id = 2},
                new {Name = "Phil", Id = 3},
                new {Name = "David", Id = 4}
            }
        };
        Console.WriteLine(template.TransformText());
        Console.ReadLine();
    }
}

The code is very straightforward. It simply instantiates an instance of the RazorTemplate class and sets the Model property (which is the property I defined within the template) as an array of anonymous objects.

Again, for demonstration purposes, I’m using a dynamic property to access anonymous objects. You can just as well pass in and render strongly typed properties.

After instantiating the template instance, we simply call the TransformText method on it and write the response to the console.

razor-output

Easy as stepping on a Lego block in the dark!

Note that using Razor as a general text templating langage might not always produce the best results. It was heavily geared towards rendering markup (aka angle brackets) which it’s very good at. Your mileage may vary when attempting to render other types of textual output.

In a following post, I’ll show you a cool way I’m using this technique for a library I’ve been working on meant to demonstrate some cool internals of ASP.NET MVC.

Related Razor Resources

Some of what I’ve shown here has been shown before in the context of ASP.NET MVC. Those other posts are worth reading as well. For example…

I hope you find this useful for your text templating needs!

What others have said

Requesting Gravatar... Tomas Aug 01, 2011 4:57 PM
# re: Text templating using Razor the easy way
Nice post. How do you combine this with the markdown syntax? And what is used to generate the documentation page from the markdown markup?
Requesting Gravatar... gOran Aug 01, 2011 9:07 PM
# re: Text templating using Razor the easy way
Nice one, i just can't wait next post about this.
Thanks for sharing!
Requesting Gravatar... pete w Aug 01, 2011 9:15 PM
# re: Text templating using Razor the easy way
Very handy, but I think you should add a caveat: for those of us building software in SharePoint, this will not currently work (as of 8/1/2011) because SharePoint runs on .NET3.5 and Razor requires the dynamic features of .NET 4.0

I once evaluated using Razor in a SharePoint solution and ended up using Castle NVelocity with works just as well for my needs
Requesting Gravatar... Ignat Andrei Aug 01, 2011 9:30 PM
# re: Text templating using Razor the easy way
Sorry for being unhandy - but I search
RazorGenerator
in Extension Manager and did not found.( neither with
Razor
, neither with
generator
)
Does it matter that I use VSWD Express?
Requesting Gravatar... Alexandre Jobin Aug 01, 2011 10:20 PM
# re: Text templating using Razor the easy way
What is the difference between RazorGenerator & RazorEngine that we can find here: http://razorengine.codeplex.com ?

are they doing the same thing but differently? Can i do an Email template and i render on the fly with RazorGenerator?

alex
Requesting Gravatar... Marcus Swope Aug 01, 2011 10:37 PM
# re: Text templating using Razor the easy way
I'm guessing this is how we are going to be writing HTML5 apps that run on Windows 8?
Requesting Gravatar... Quentin Aug 02, 2011 12:30 AM
# Can we use Layouts this way?
Is it possible to use a separate layout file when generating templates this way? That always seemed to pose a hurdle with previous razor generating techniques, like the aforementioned codeplex project.
Requesting Gravatar... sab Aug 02, 2011 5:19 PM
# re: Text templating using Razor the easy way
I could not find the package
nuget.org/.../Search
Requesting Gravatar... Buildstarted Aug 03, 2011 12:30 AM
# re: Text templating using Razor the easy way
Alexandre, the difference is that this is a precompiled method while the RazorEngine compiles on the fly. The RazorEngine allows you to pull views from alternate locations that can be modified if necessary. This particular method just compiles them ahead of time.
Requesting Gravatar... Buildstarted Aug 03, 2011 12:32 AM
# re: Text templating using Razor the easy way
Ignat, visualstudiogallery.msdn.microsoft.com

Sab, you're looking for "PrecompiledMvcViewEngine" instead. nuget.org/List/Packages/PrecompiledMvcViewEngine
Requesting Gravatar... David Ebbo Aug 03, 2011 1:50 AM
# re: Text templating using Razor the easy way
@tomas: see the code in http://nugetdocs.codeplex.com/ for details on how the nuget doc site works.
Requesting Gravatar... David Ebbo Aug 03, 2011 1:54 AM
# re: Text templating using Razor the easy way
@pete_w: the 4.0 requirement is a general Razor engine thing, and not specific to RazorGenerator.

@Ignat: VS express indeed does not support most extensions, so it won't work there.
Requesting Gravatar... David Ebbo Aug 03, 2011 2:01 AM
# re: Text templating using Razor the easy way
@Alexandre: I haven't used RazorEngine, but from what I can see, it's quite different, in the sense that it is a runtime library while RazorGenerator is a design time tool. With RazorGenerator, code gets generated and compiled as part of your project, such that at runtime there is no dependency on Razor, and no on-the-fly compilation. See my posts on RazorGenerator (http://blog.davidebbo.com/search/label/Razor) to see examples of what it's good for.
Requesting Gravatar... David Ebbo Aug 03, 2011 2:05 AM
# re: Text templating using Razor the easy way
@Quentin: could you start a discussion on http://razorgenerator.codeplex.com/ with more details about the layout scenario you have in mind? It's possible that we can do something there, but we need to make sure we're talking about the same thing :)
Requesting Gravatar... krislig Aug 03, 2011 5:56 AM
# re: Text templating using Razor the easy way
I know that this is crazy but:

Can you use Razor Engine to generate XAML markup to produce this ugly XML like file in WPF projects?
Requesting Gravatar... Micah Smith Aug 03, 2011 8:57 AM
# re: Text templating using Razor the easy way
Thank you for writing this--today i was searching for different template languages to use against xml. I often get "can you use XSLT 2.0" questions about a .NET product we use, and since 1) microsoft hasn't moved to XSLT 2.0 and 2) why would they? Newer template languages like razor/jade/haml have ushered in an era of a much more syntactically friendly form and well... As soon as i hit this "leave your mark" button below this form i'm going to search "xml to dynamic .NET" on google. Thanks phil
Requesting Gravatar... Josh Aug 04, 2011 9:42 AM
# What about T4
So what about T4?

I know this isn't a fair analogy, but it reminds me of the Linq2Sql vs Entity Framework issue.

We now have two competing technologies within the MS stack that overlap a bit. Razor has a nicer syntax, is lighter weight, and more specialized. Whereas T4 is more general purpose, but the learning curb is a bit steeper...

Personally... I think it would be awesome if T4 adopted a more razor like syntax. Are the two sides talking, or is this just wishful thinking on my part :)
Requesting Gravatar... haacked Aug 04, 2011 1:38 PM
# re: Text templating using Razor the easy way
@Josh I think it's pretty extreme to compare this to the Linq2Sql and EF comparisons.

T4 is primarily a general purpose text transformation language. Razor is optimized for HTML generation. If you try and generate C# code with Razor, you'll find it's a bit painful. That's not it's sweet spot nor its design intention.
Requesting Gravatar... Mikhail Petrovskikh Aug 11, 2011 6:43 AM
# @helper
I tried to add an in-page razor helper in my template with "@helper HelperName(){}" syntax. It looks like the code generated by the Razor Generator is missing some references to System.Web.WebPageExecutingBase for static methods WriteTo and WriteLiteralTo. When I added @using System.Web in the template and prepended these functions with the class name "WebPageExecutingBase." everything worked fine but it gets overwritten if you change the template(obviously).
Requesting Gravatar... Jadall Aug 29, 2011 3:00 PM
# re: Text templating using Razor the easy way
Josh, you must be high out of your mind
Requesting Gravatar... simon weaver Sep 19, 2011 4:48 AM
# Where to find DLLS!???
@haacked can you add a note explaining where to find

System.Web.WebPages.dll
System.Web.Helpers.dll
System.Web.Razor.dll

I had a WPF project that i had to change from .NET Framework 4 Client Profile > .NET Framework 4 to be able to see these DLLS under 'Add Reference'. I think that's the correct way right?
Requesting Gravatar... simon weaver Sep 19, 2011 5:18 AM
# re: Text templating using Razor the easy way
In addition to the extension, the latest version of the Razor Generator requries the Nuget package RazorGenerator.Templating for the RazorGenerator.Templating.RazorTemplateBase base class

razorgenerator.codeplex.com/discussions/271171

Requesting Gravatar... ctrlShiftBryan Oct 20, 2011 4:31 AM
# re: Text templating using Razor the easy way
Thanks Simon for the hint at needing to

PM> Install-Package RazorGenerator.Templating

What do you have to say?

(will show your gravatar)
Please add 8 and 6 and type the answer here: