Content by Category
.NET 1.x
.NET 2.0
.NET 3.0
.NET 3.5
.NET 4.0
.NET 4.5
.NET Assemblies
.NET Framework
.NET Getting Started
Accessibility
ADO.NET
Advertorials
Agile Development
AJAX
Amazon Web Services
Analysis Services
Android
Architecture
Arduino
ASP .NET Web API
ASP.NET
ASP.NET MVC
ASP.NET WebForms
Azure
B2B (Business Integration)
BDD
Big Data
Bing
BizTalk
Book Excerpts
Build and Deploy
Business Intelligence
C#
C++
ClickOnce
Cloud Computing
Code Contracts
CODE Framework Info - non Technical
CODE on the Road!
COM+
Community
Conferences
Continuous Integration
Crystal Reports
CSLA.NET
CSS
Data
Debugger
Design Patterns
Development Process
Display Technologies
Distributed Computing
Document Database
DotNetNuke
DSL
Dynamic Languages
Dynamic Programming
Editorials
Enterprise Services ("COM+")
Entity Framework
Events
Expression Blend
F#
Fox to Fox
Frameworks
Functional Programming
Git
Graphics
HTML 5
Internet Explorer 8.0
Interviews
IOS
iPhone
Iron Ruby
Java
Java Script
JavaScript
jQuery
JSON
Lightswitch
LINQ
Linux
LUA
Mac OS X
MDX
Messaging
Metro
Microsoft Application Blocks
Microsoft Business Rules Framework
Microsoft Dynamics
Microsoft Expression
Microsoft Office
Mobile Development
Mobile PC
Mono
MsBuild
MVVM
MySQL
Network
NHibernate
node.js
NOSQL
Nuget
Object Oriented Development
Objective C
Odata
OLAP
Open Source
Opinion
Opinions
Oracle
ORM
Other Languages
Parallel Programming
Patterns
PHP
Podcasts
Post Mortem
PowerPoint
Print/Output
Prism
Product News
Product Reviews
Project Management
Prolog
Python
Q&A
Rails
Rake
Razor
Reporting Services
REST
RIA Services
Ruby
Ruby on Rails
Scheme
Search
Security
Services
SharePoint
SignalR
Silverlight
SOA
Social Networks
Software & Law
Software Business
Source Control
Speech-Enabled Applications
SQL Server
SQL Server 2000
SQL Server 2005
SQL Server 2008
SQL Server 2012
SQL Server CE/AnyWhere/Mobile/Compact
SSIS
Subversion
Sync Framework
Tablet PC
TDD
Team System
Techniques
Testing and Quality Control
TFS
Tips
TypeScript
UI Design
UML
User Groups
VB Script
VB.NET
Version Control
VFP and .NET
VFP and SQL Server
Virtual Earth
Vista
Visual Basic
Visual Basic 6 (and older)
Visual FoxPro
Visual Studio .NET
Visual Studio 11
Visual Studio 2005
Visual Studio 2008
Visual Studio 2010
Visual Studio 2011
Visual Studio 2012
Visual Studio Tools for Office
VSX
WCF
Web Development (general)
Web Services
WebMatrix
WF
Whitepapers
Windows 7
Windows 8
Windows Azure
Windows Live
Windows Phone 7
Windows Phone SDK
Windows Server
Windows Vista
WinForms
WinRT
Workflow
WPF
XAML
Xiine Documentation
XML
XNA
XSLT



LearnNow


XAMALOT
 


SSWUG

Reader rating:
Article source: CoDe (2011 Mar/Apr)


Article Pages:  1  2 3 4 - Next >


Leveraging Razor Templates Outside of ASP.NET: They’re Not Just for HTML Anymore!

The Razor syntax is much more than just a clean way to write ASP.NET MVC Views and WebMatrix web pages. In fact, with a working knowledge of the Razor API, you can leverage Razor templates in any application. The Razor API exposes a powerful library for parsing, compiling, and executing templates created using the Razor syntax.

This article will explore the Razor API and follow the lifetime of a Razor template from text to powerful templating solutions, including examples such as unit testing ASP.NET MVC views and creating a highly-maintainable email generator.

The Razor Template Lifecycle

Figure 1 shows the lifecycle of a Razor template.

Click for a larger version of this image.

Figure 1: The Razor template lifecycle.

Templates based on the Razor syntax combine code and content in powerful ways. The Razor API translates these plain text templates to .NET source code - the same kind of source code that you and I write every day. Just as with the source code that we developers write, Razor API-generated code compiles into new .NET types just like any other: simply create and execute a new instance to produce a rendered result!

Meet the Players

Before jumping into exactly how the API works, here is a quick overview of the relatively small number of components involved in the process of transforming a plain text template into an executable Razor template class:

  • RazorEngineHost: Contains the metadata required for creating Razor Templating Engines. Things like the base class name, output class name (and namespace), as well as the assemblies and namespaces required to execute the generated template.
  • RazorTemplateEngine: Using configuration data provided by a RazorEngineHost, the Template Engine accepts a stream of text and transforms this text into .NET code (represented by a CodeCompileUnit) that gets compiled into a .NET type.
  • Custom Template Base Class: Though not technically part of the Razor API, the Razor Templating Engine requires a custom template base class to use as a base class for the generated template type.
  • CodeDomProvider: Also not technically part of the Razor API, the CodeDomProvider class (from the System.CodeDom.Compiler namespace) compiles CodeCompileUnits into .NET Types, making them available for .NET applications to consume. The Razor Templating API offers two CodeDomProvider implementations to compile RazorTemplateEngine-generated CodeCompileUnits: The CSharpCodeProvider and VBCodeProvider. As their names indicate, these two implementations compile C#- and Visual Basic-based Razor templates respectively.

Compiling Templates with the Razor API

Consider the Razor template which renders customer order information shown below.

Customer ID:   @Order.CustomerID
Customer Name: @Order.CustomerName
Order ID:      @Order.ID

Items:
Quantity      Unit Price     Product

@foreach(var item in @Order.LineItems) {
  @item.Quantity  @item.Price  @item.ProductName


Tax:          @Order.Tax
Order Total:  @Order.Total

As you’ll soon see, the Razor Templating API provides the ability to transform this template into a .NET class and execute it against a model, rendering the output shown below.

Customer ID:     HSIMPSON
Customer Name:   Homer Simpson
Order ID:        1234

Items:
Quantity         Unit Price    Product
   1               $1.50       Jelly Doughnut
   4               $0.75       Glazed Doughnut

Tax:          $0.10
Order Total:  $4.60

Obviously, the customer order information template includes nothing inherently web related, so why should rendering it depend on the ASP.NET runtime? Luckily, it doesn’t have to. In fact, the output displayed in the previous snippet is the result of a command line application using the code snippets from this article!

Configuring the Razor Template Engine

The RazorTemplateEngine class does most of the heavy lifting to transform Razor template text into usable .NET source code. Before creating a RazorTemplateEngine, however, the application must provide a set of properties that inform the engine about how to properly translate the Razor template text it receives. These properties come in the form of a RazorEngineHost.

Creating a RazorEngineHost

The code snippet below contains an example RazorEngineHost initialization.

var language = new CSharpRazorCodeLanguage();
var host = new RazorEngineHost(language) {
   DefaultBaseClass = "OrderInfoTemplateBase",
   DefaultClassName = "OrderInfoTemplate",
   DefaultNamespace = "CompiledRazorTemplates",
};

// Everyone needs the System namespace, right?
host.NamespaceImports.Add("System");

To begin, the RazorEngineHost’s constructor accepts a RazorCodeLanguage specifying the target template’s code language. This example produces a host that can parse Razor templates written using C#. To support templates written in Visual Basic, supply a VBRazorCodeLanguage instance instead. The additional initializer properties instruct the code generator to emit code with a particular class name, deriving from a custom template base class, and residing in a particular namespace. Finally, add the System namespace to the list of imported namespaces required for the generated class to compile just as you would import a namespace in a normal, hand-written class.

The custom template base class - in this example named OrderInfoTemplateBase - is somewhat special. Though it does not need to implement any “official” .NET interface, the base class does need to provide methods with the following signatures:

  • public abstract void Execute()Once populated with generated code, this method contains a series of calls to the Write methods to render the template contents.
  • void Write(object value) and void WriteLiteral(object value)The RazorTemplateEngine populates the Execute() method with calls to the Write() and WriteLiteral() methods, much like using an HtmlTextWriter to render a Web Forms server control. While the Execute() method controls the flow of the template rendering, these two methods do the heavy lifting by converting objects and literal strings to rendered output.

This next code snippet contains the simplest possible implementation of a Razor template base class.

public abstract class OrderInfoTemplateBase
{
  public abstract void Execute();

  public virtual void Write(object value)  
  { /* TODO: Write value */ }

  public virtual void WriteLiteral(object value)
  { /* TODO: Write literal */ }
}

While this implementation will, of course, do nothing to render any content, it is the minimum code required to successfully compile and execute a template class. Later sections in this article will revisit and expand upon this class, making it much more useful.

&

By: Jess Chadwick

Jess is independent software consultant. He has over eight years experience with .NET technologies ranging from embedded devices in start-ups to enterprise-scale Web farms at Fortune 500 corporations. He is a Microsoft MVP in ASP.NET, technical editor of Silverlight 3 Programmers Reference (Wrox) and is actively involved with the community, acting as leader of the NJDOTNET Central New Jersey .NET user group. Jess also tries his hardest to maintain an active blog, hosted at http://blog.jesschadwick.com.

jesschadwick@hotmail.com



Article Pages:  1  2 3 4 - Next Page: 'Creating the RazorTemplateEngine' >>

Page 1: Leveraging Razor Templates Outside of ASP.NET: They’re Not Just for HTML Anymore!
Page 2: Creating the RazorTemplateEngine
Page 3: Putting the Razor Templating Engine to Work
Page 4: Code Generators Generating Code Generators

How would you rate the quality of this article?
1 2 3 4 5
Poor      Outstanding

Tell us why you rated the content this way. (optional)

Average rating:
1.3 out of 5

48 people have rated this article.

Instantly Search Terabytes Of Text
“Lightning Fast”
– Redmond Mag
“Covers all data
sources” – eWeek
25+ fielded & full-text search options
dtSearch’s own document filters highlight hits in popular file types
Web Spider supports static & dynamic data
APIs for .NET, Java, C++, SQL, etc.
Win / Linux (64-bit & 32-bit)
www.dtSearch.com
 

      AppsWorld Europe

 

SSWUG