Chapter 1. Introduction

HyperText Markup Language (HTML) makes the World Wide Web possible. Every website uses HTML to render content, and much of HTML’s popularity derives from its simplicity: with knowledge of just a few concepts, anyone can publish content to the Web.

HTML may be a way of life for web developers, but when it comes to creating dynamic, data-driven websites, most developers turn to some kind of tool to make the job of generating HTML easier. Razor is one of those tools: a scripting syntax for making templates and web content on Windows-based web servers.

This book is designed to get you acquainted with the Razor syntax and how it fits into the two primary Microsoft development environments: ASP.NET MVC and WebMatrix. The final chapters will dive deeper, cracking open the underlying tooling and API to see what makes this all possible. By the end of this book, not only will you know how to create great Razor-based websites, but you will also be able to add custom extensions and make Razor even better suited to the specific needs of your projects!

A Brief History of Microsoft’s Web Development Platforms

Long ago, Microsoft saw the need for a Windows-based web development platform and worked hard to produce a solution. Over the last two decades, Microsoft has given the development community several web development platforms.

Active Server Pages (ASP)

Microsoft’s first answer to web development was Active Server Pages (ASP), a scripting language in which code and markup are authored together in a single file, with each physical file corresponding to a page on the website. ASP’s server-side scripting approach became widely popular and many websites grew out of it; some continue to serve visitors today! After a while, though, developers wanted more: things like easier code reuse, better separation of concerns, and easier application of object-oriented programming principles. In 2002, Microsoft offered ASP.NET as a solution to these concerns.

ASP.NET Web Forms

Like ASP websites, ASP.NET websites rely on the page-based approach, where each page on the website is represented in the form of a physical file (called a Web Form) and is accessible using that file’s name. Unlike a page using ASP, a Web Forms page provides some separation of code and markup by splitting the web content into two different files: one for the code and one for the markup. ASP.NET and the Web Forms approach served developers’ needs for years and continues to be the web development framework of choice for many .NET developers. Some .NET developers, however, consider the Web Forms approach too much of an abstraction from the underlying HTML, JavaScript, and CSS. Gee, some developers just can’t be pleased! Or can they?

ASP.NET MVC

Microsoft was quick to spot the growing need in the ASP.NET developer community for something different from the page-based Web Forms approach, and it released the first version of ASP.NET MVC in 2008. Representing a total departure from the Web Forms approach, ASP.NET MVC abandons the page-based architecture completely, using a Model-View-Controller (MVC) architecture instead. Though it still leverages much of the previous framework, ASP.NET MVC represents an entirely separate stack. Instead of markup files, views take the responsibility for rendering HTML to the user. ASP.NET MVC leaves it up to application developers to choose the syntax they use to author views. Razor is quickly emerging as the most popular ASP.NET MVC view syntax for reasons that should become quite clear while reading this book!

WebMatrix

Released at the same time as ASP.NET MVC 3 in early 2011, WebMatrix is Microsoft’s simple, straightforward, and free web development environment. Comprising a simple integrated development environment (IDE) and an API (named Web Pages), WebMatrix is a natural fit in the evolution of Microsoft’s web development frameworks. WebMatrix offers a middle ground for those who view ASP as a hindrance to object-oriented development, ASP.NET Web Forms as too much of an abstraction from core HTML/CSS/JavaScript, and ASP.NET MVC as too complex.

At a glance, WebMatrix web pages bear a strong resemblance to ASP web pages, in that they combine business logic and markup in the same file. However, if you dig deeper, you’ll quickly find a very object-oriented foundation lurking underneath. By combining the power of the ASP.NET platform with the simplicity of ASP-like scripting syntax (the Razor syntax), WebMatrix offers a web development environment that is approachable by a very broad range of website developers. WebMatrix is straightforward enough to allow a hobbyist to produce a simple website, yet powerful enough to satisfy the needs of more advanced web applications.

Hello, Razor!

Razor is a template syntax that allows you to combine code and content in a fluid and expressive manner. Though it introduces a few symbols and keywords, Razor is not a new language. Instead, Razor lets you write code using languages you probably already know, such as C# or Visual Basic .NET.

Razor’s learning curve is very short, as it lets you work with your existing skills rather than requiring you to learn an entirely new language. Therefore, if you know how to write HTML and make a .NET API call, you can easily write markup like the following:

<div>This page rendered at @DateTime.Now</div>

which produces output like this:

<div>This page rendered at 12/7/1941 7:38:00 AM</div>

This example begins with a standard HTML tag (the <div> tag), followed by a bit of static text. In the midst of all of this is some dynamic text rendered via a call to the .NET System.DateTime object, followed by the closing (</div>) tag.

Razor’s intelligent parser allows developers to be more expressive with their logic and make easier transitions between code and markup. The more advanced the markup, the easier it is to see how Razor’s syntax is cleaner and more expressive than the Web Forms syntax. Compare the following scenarios, each one showing the Razor markup and Web Forms markup required to produce the same HTML:

if/else statement using Web Forms syntax
<% if(User.IsAuthenticated) { %>
        <span>Hello, <%= User.Username %>!</span>
<% } %>
<% else { %>
        <span>Please <%= Html.ActionLink("log in") %></span>
<% } %>
if/else statement using Razor syntax
@if(User.IsAuthenticated) {
    <span>Hello, @User.Username!</span>
} else {
    <span>Please @Html.ActionLink("log in")</span>
}
foreach loop using Web Forms syntax
<ul>
<% foreach( var post in blogPosts) { %>
    <li><a href="<%= post.Href %>"><%= post.Title %></a></li>
<% } %>
</ul>
foreach loop using Razor syntax
<ul>
@foreach( var post in blogPosts) {
    <li><a href="@post.Href">@post.Title</a></li>
}
</ul>

Though the difference between the Web Forms syntax and Razor syntax is only a few characters, those characters make a big difference in the readability of the markup! One of the loudest complaints from developers attempting to use Web Forms to author dynamic markup is that its “angle-bracket” syntax is so verbose that it can distract from the page’s logic and content. Additionally, because the Web Forms syntax itself so closely resembles HTML markup, it is often difficult to determine at a glance which parts of the template are code and which are markup.

In direct contrast, Razor uses minimal markup to perform the same tasks. What’s more, Razor’s syntax was deliberately designed to blend in with HTML, not conflict with it.

Differentiating Code and Markup

Razor provides two ways to differentiate code from markup: code nuggets and code blocks.

Code Nuggets

Code nuggets are simple expressions that are evaluated and rendered inline. They can be mixed with text and look like this:

 Not Logged In: @Html.ActionLink("Login", "Login")

The expression begins immediately after the @ symbol, and Razor is smart enough to know that the closing parenthesis indicates the end of this particular statement. The previous example will render this output:

 Not Logged In: <a href="/Login">Login</a>

Notice that code nuggets must always return markup for the view to render. If you write a code nugget that does not return anything (i.e. returns void), you will receive an error when the view executes.

Code Blocks

A code block is a section of the view that contains strictly code rather than a combination of markup and code. Razor defines a code block as any section of a Razor template wrapped in @{ } characters. The @{ characters mark the beginning of the block, followed by any number of lines of code. The } character closes the code block.

Keep in mind that the code within a code block is not like code in a code nugget. It is fully-formed code that must follow the rules of the current language; for example, each line of code written in C# must include a semicolon (;) at the end, just as if it lived within a class in a .cs file.

Here is an example of a typical code block:

@{
 LayoutPage = "~/Views/Shared/_Layout.cshtml";
 View.Title = "Product Details for " + Model.ProductName;
}

Code blocks do not render anything to the page. Instead, they allow you to write arbitrary code that requires no return value. Variables defined within code blocks may be used by code nuggets in the same scope. That is, variables defined within the scope of a foreach loop or similar container will only be accessible within that container. Variables that are defined at the page level (not in any kind of container) will be accessible to any other code blocks or code nuggets in the page.

To clarify this, take a look at a view with a few variables defined at different scopes:

@{
    // The customer and order variables are
    // available to the entire page
    var customer = Model.Customer;
    var order = Model.Order;
}

<h1>@customer.Name' Order Details<h1>
<div class="items">
<!-- Loop through the Items property on the order variable -->
@foreach(var item in order.Items) {
    <!-- The item variable is only available within the foreach loop -->
    <div>
        <!-- A hyperlink builds a URL to the Order Item
             page using the Order ID and the Item ID -->
        <a href="/orders/@order.ID/@item.ID">@item.Name</a>
    </div>
}

<!-- This will throw an error: the item variable does not exist at this scope! -->
<div>Last Item: @item.Name</div>
</div>

Code blocks are a means to execute code within a template and do not render anything to the view. In direct contrast to the way that code nuggets must provide a return value for the view to render, the view will completely ignore values that a code block returns.

How Razor Parses Markup and Code

The @ symbol is the heart of the Razor syntax, the character that Razor uses to differentiate code from markup. The @ symbol marks a point at which the developer intends to switch from markup to code. In simple cases, no additional characters are needed to indicate when the code stops and the markup resumes. Razor’s intelligent parser determines which parts of the template are code and which are markup.

What makes a valid code statement? Razor uses the following algorithm to find the end of a code statement once it reads the @ symbol trigger:

  1. Read to the end of a valid identifier (i.e., a C# or VB keyword) or variable name.

  2. If the next character is an opening bracket ( ( or [ )…

    1. Keep parsing until the corresponding closing bracket is located. Nested brackets are also tracked to avoid premature closing of a block.

    2. Loop back to #2.

  3. If the next character is a . (period) and precedes a valid identifier, jump to #1.

  4. Complete the code statement and continue processing the rest of the markup.

Razor relies on the current language’s syntax to determine the end of a code statement. Razor also attempts to “read forward,” checking if the upcoming content resembles code or markup. The specifics depend on the language currently in use (C# or VB).

Here’s a typical Razor snippet:

@foreach(var item in order.Items) {
    <li>@item.Name</li>
}

The first line initializes the loop variables and opens the loop with an opening bracket; the second line renders markup; and the third line contains the closing bracket to end the loop. There is a clear transition between code and markup because the second line begins with an <li> tag that is clearly an HTML element and the third line is clearly the foreach loop’s closing tag.

In this example there is another line of code following the initial opening foreach line:

@foreach(var item in order.Items) {
    var itemName = item.Name;
    <li>@itemName</li>
}

Since the second line follows the variable initialization C# syntax, Razor continues to correctly interpret this second line as C# code, as opposed to markup, and executes it as such. As it continues parsing, Razor correctly assumes that the third line is markup and renders it correctly. The final line is code again: the closing bracket for the foreach loop.

Disambiguating Code and Markup

Consider a third example, this time with C# generics syntax thrown into the mix:

@foreach(var item in order.Items) {
    var itemName = GetOrderItemName<string>(item);
    <li>@itemName</li>
}

In this example, the second line contains a generic parameter. While this is perfectly valid C# code, the bracket-based C# generic syntax is practically indistinguishable from HTML. Thus, the Razor parser gets confused and cannot determine whether to interpret the line as code or markup. Razor responds by giving up and throwing an exception.

While Razor’s ability to differentiate between code and markup is generally impressive, this example shows that there are certainly scenarios that it cannot accurately parse. In these scenarios, there are several ways to explicitly state your intent and disambiguate code from markup.

Explicit code nuggets

The explicit code nugget syntax (@( )) allows you to wrap a code statement, unambiguously marking the beginning and end of the statement. The explicit code nugget syntax lets you give Razor some guidance about how your markup should be interpreted.

Here is an example in which Razor incorrectly assumes that the . in the filename extension is part of the code statement, resulting in a call to the (nonexistent) property Product.Name.jpg:

<img src="/products/@Product.Name.jpg" />

The explicit code nugget syntax clears things right up, wrapping the code to separate it from content:

<img src="/products/@(Product.Name).jpg" />

The same syntax can be applied to differentiate the generic parameter in the example at the beginning of this section. In this example, however, the preceding @ character is not required because the trouble spot is already within a code statement:

@foreach(var item in order.Items) {
    var itemName = ( GetOrderItemName<string>(item) );
    <li>@itemName</li>
}

The @: character sequence

The @: character sequence indicates a transition, telling Razor to assume that the content that follows the sequence is content, not code. You are still free to use the @ symbol any time after transitioning to content mode to execute code, just as in any other part of the Razor template. The following example shows the @: character sequence in action:

@if(User.IsAuthenticated) {
    @:Hello, @User.Name!
}
else {
    @:Please login
}

The conditional markup in this example does not specify any HTML, so it is difficult for Razor to figure out when or if to transition to markup mode. After all, how can Razor know whether “Hello” is a class name or an arbitrary word? The markup in the if condition uses the @: character sequence to specify that “Hello” is actually content and not code. The same markup then switches back to code mode to render the value of the User.Name property. The markup in the else condition also uses the @: character sequence to indicate that the text should be rendered verbatim.

The <text> block

The <text> block is an alternative to the @: character sequence that allows you to denote that an entire portion of a template is content. <text> is useful in scenarios where multiple lines of markup can be interpreted as code or text, such as:

@if(!User.IsAuthenticated) {
    <text>
    Guests are not allowed to view this content.
    Please @Html.ActionLink("login", "Login") to view.
    </text>
}

which produces the following output when the user is not authenticated:

    Guests are not allowed to view this content.
    Please <a href="/Login">login</a> to view.

As you can see, the opening and closing <text> tags are only used within the template to mark the beginning and end of the block of content and are not rendered along with the content. The example also shows that code statements are still perfectly acceptable within a <text> block.

There are plenty of circumstances that confuse Razor. By default, it will assume that ambiguous markup is code. Consider the @: character sequence and <text> blocks as a way to tell Razor “whenever you are unsure about whether something in this block is code or content, it is content!”

Comments

Many developers strive to write code in such a way that the code documents itself. Sometimes, however, it’s not possible; perhaps there is a particularly complex bit of markup, or you need to leave a note for the next developer to come along (who might be you). Or you need to temporarily exclude a portion of a template without deleting it entirely.

To support these scenarios, Razor lets you comment out portions of markup with the @* *@ syntax. Any markup wrapped in a Razor comment block will remain in the template but will not have any effect on rendering.

Here is a simple Razor template with a few parts commented out:

First
@* Second *@
Third @* Fourth *@ Fifth

This template renders the output:

First

Third Fifth

The Second and Fourth words are not included in the output, and are completely ignored by Razor.

Tip

Comment blocks open with the @* characters and close with the *@ characters, regardless of where they appear. Comment blocks can exclude only a small part of a line or span multiple lines.

Get Programming Razor now with O’Reilly online learning.

O’Reilly members experience live online training, plus books, videos, and digital content from 200+ publishers.