Introduction
Microsoft has introduced a new view engine called Razor that replaces ASPX as the default view engine in ASP.NET MVC3. Razor represents a major improvement for developers that want a cleaner and more efficient view engine with fewer keystrokes. Razor also allows the developer full control of every character sent to the browser including whether or not the ASP.NET JavaScript libraries are used at all.
Pre-requisites
First, install ASP.NET MVC3 Release Candidate 2 from ASP.NET. This release candidate has go-live licensing and runs on the 4.0
version of the .NET framework so you can build applications in MVC3 and deploy them to an existing production server.
The configuration changes you will need to
make to deploy your MVC3 application are the same as previous versions of MVC. This article assumes familiarity with ASP.NET MVC.
Basic Syntax
Razor does away with ASP’s <% %> block types and instead intelligently infers what is intended to be server side code versus client side code. The at (@) symbol is used to denote a server side statement and the double @@ is how you include a literal @ symbol on your page.
The example below shows an if statement that will be run server side and the text inside of the if block will be written to the web page including the value of the session variable CartCount
. In the statement below, the code flows smoothly between server side and client side code. For someone who is used to working in ASP.NET’s codified code blocks, working in Razor can take some adjustment but you will be rewarded with a page syntax that has far fewer keystrokes and better intellisense support.
@if(Session["CartCount"] != null) { Take you have @Session["CartCount"] items in your basket. }
Razor comments are performed server side to minimize the size of the web pages sent to the client. The @* *@ comment format works in a multi-line comment fashion similar to the html <!– –> or C# /* */.
@* This is a comment. It won't get sent to the user's browser. It is a multi-line comment type. *@
Razor uses the same syntax for both single and multi-line code blocks. The only difference is for multi-line blocks you should end each line with a semicolon.
@{ String s = "MyString"; s = s.ToUpper(); }
Layout Pages
Many of the core concepts of ASPX translate well to Razor including Layout pages which are Razor’s master pages equivalent. When you create a blank MVC3 application, the default layout template is in /Views/Shared/_Layout.cshtml. You can create additional layout pages and reference them at the top of your individual Razor .cshtml views shown below.
@{ Page.Title="Your Page Title"; Layout = "~/Views/Shared/MyCustomLayout.cshtml"; }
Inside the layout page itself, @RenderBody() defines where the page that uses your layout page will render its content. You can optionally, also implement a reference to @Page.Title
if you want your layout page to have a proper HTML title.
It is possible to define as many custom sections as needed in your layout page using the @RenderSection
function. If it is marked as required, the page will throw an exception if the view utilizing the layout does not define the section.
@RenderSection("RazorIntroSection", required:true)
To define the custom section in your corresponding view page, use the @section
function along with your section name. All of the HTML and functions inside of the brackets will be a part of that sub-section.
@section RazorIntroSection { <p>This is the razor intro section defined in my view.</p> }
Links and HTML
Throughout your Razor views, you will need to reference controller URLs as well as content files such as images. For this purpose Razor includes the @Url.Content
and @Url.Action
functions. Similar to ASP.NET you can pass these functions the path desired preceded by the tilde (~) which is a reference to the virtual root of your site.
<a href="@Url.Content("~/Content/Images/Vacation.png")">Look at my vacation!</a>
The @Url.Action
function allows you to reference MVC paths directly or to use more advanced properties.
By default, strings containing HTML markup such as comments made using a rich text box stored in your database are automatically escaped by Razor. This means <p>This is a paragraph</p> would be automatically translated by Razor into <p>This is a paragraph</p> when the page is run. This is done for mostly security reasons to prevent cross site scripting attacks. If you want Razor to output the HTML exactly as it is stored in your string without escaping it, use the @MvcHtmlString
function shown below.
@MvcHtmlString.Create("<p>This is a paragraph.</p>")
The Model
At the top of your Razor page, you can optionally define an @model
type. Doing so isn’t required but if you define it, intellisense will work correctly across your page and compile time validation will be performed accurately on your view. In the example below, if your view returns List<string>, you can iterate that list as shown below with full intellisense support.
@model List<string> @{ Layout = "~/Views/Shared/_Layout.cshtml"; Page.Title = "Model Bound Page"; } <p>This is my list:<p> <table><tbody> @foreach(string label in Model) { <tr><td>@label .ToUpper()</td></tr> } </tbody></table>
To pass your model from your controller to your view, simply return it as part of the View function as shown in the listing below. You can pass any kind of object from your controller to your view including non-serializable objects.
namespace IntroducingRazor.Controllers { public class HomeController : Controller { public ActionResult Index() { List<string> MyList = new List<string>(); MyList.Add("Hello"); MyList.Add("How"); MyList.Add("Are"); MyList.Add("You?"); return View(MyList); } } }
In a perfect world, your views should align well to your model and you should be able to keep as much logic out of your view as possible. In some situations you will find yourself needing to provide multiple unrelated objects to your Razor view in order to meet your project requirements. Doing this can be done quickly and easily leveraging the .NET Framework 4.0 Tuple.
@model Tuple<List<Product>,List<RSSFeed>> <ul> @foreach(Product product in Model.Item1) { <li>Product: @product.ProductName</li> } </ul> <ul> @foreach(RSSFeed feed in Model.Item2) { <li>Feed: @feed.FeedName</li> } </ul>
Putting it together
The included code example was created by choosing New->Project then choosing ASP.NET MVC3 Web Application. The following dialog selected “Empty” and accepted the default values including the View engine as “Razor”. This code example was kept intentionally very simple to provide a good starting point for understanding how Razor sites are put together.
Conclusion
Razor provides the most productive .NET framework view syntax yet. It is the most powerful, clean and concise way to define web views on the .NET framework platform.