How to render a Razor template with PowerShell

Posted on 29.04.12

2



The Microsoft ASP.NET Razor view engine has an API that can be leveraged outside of the normal ASP.NET MVC context. In this post we are going to use PowerShell to render a Razor template. Lets get started.

First of all we have to load the System.Web.Razor.dll assembly:

Add-Type -Path path\to\System.Web.Razor.dll

There are three classes in the Razor API we have to use:

Let us create instances of these:

$language = New-Object `
    -TypeName System.Web.Razor.CSharpRazorCodeLanguage
$engineHost = New-Object `
    -TypeName System.Web.Razor.RazorEngineHost `
    -ArgumentList $language `
    -Property @{
        DefaultBaseClass = "TemplateBase";
        DefaultClassName = "Template";
        DefaultNamespace = "Templates";
    }
$engine = New-Object `
    -TypeName System.Web.Razor.RazorTemplateEngine `
    -ArgumentList $engineHost

Next we create a Razor template and generate code.

$template = "Hello World!"
$templateReader = New-Object `
    -TypeName System.IO.StringReader `
    -ArgumentList $template
$code = $engine.GenerateCode($templateReader)

The generated code is of type System.Web.Razor.GeneratorResults which has the property GeneratedCode which is of type System.CodeDom.CodeCompileUnit. From a CodeCompileUnit we are able to generate the template’s source code with the C# compiler:

$codeWriter = New-Object -TypeName System.IO.StringWriter
$compiler = New-Object `
    -TypeName Microsoft.CSharp.CSharpCodeProvider
$compiler.GenerateCodeFromCompileUnit(
    $code.GeneratedCode, $codeWriter, $null
)
$templateCode = $codeWriter.ToString()

The resulting C# code, which is stored in the $templateCode variable, looks like:

//------------------------------------------------------------------------------
// 
//     Koden er generert av et verktøy.
//     Kjøretidsversjon:4.0.30319.17379
//
//     Endringer i denne filen kan føre til feil virkemåte, og vil gå tapt hvis
//     koden genereres på nytt.
// 
//------------------------------------------------------------------------------

namespace Templates {

    public class Template : TemplateBase {

#line hidden

        public Template() {
        }

        public override void Execute() {
WriteLiteral("Hello World!");

        }
    }
}

We can see that this code will not compile. The Template class inherits from a TemplateBase class, overrides an Execute method and uses a WriteLiteral method. We have to implement the required TemplateBase class so that we can compile the template C# code:

$allCode = @"
using System;

namespace Templates {

    public abstract class TemplateBase {
        public abstract void Execute();
        public virtual void WriteLiteral(object value) {
            Console.Write(value);
        }
    }
}
"@ + "`n" + $templateCode
Add-Type -TypeDefinition $allCode

Finally we need to create an instance of our compiled template and execute it:

$templateInstance = New-Object -TypeName Templates.Template
$templateInstance.Execute()

The Execute method emits a simple Hello World!.

PowerShell code in this post is based on a project of mine called Razor.Render.CommandLine. Take a look at it’s source code for an extended example on how to render a Razor template with PowerShell. The source code is located here:

https://github.com/knutkj/misc/blob/master/PowerShell/Razor/Render-RazorTemplate.ps1.

Install the Razor.Render.CommandLine NuGet package to render Razor templates from the NuGet Package Manager Console inside of Visual Studio.

I would not have been able to render Razor templates with PowerShell if it hadn’t been for the book Programming Razor which I just finished reading. Have a look at it if you want to dig deep into Razor.

Advertisements
Posted in: Uncategorized