With the transition to the Razor view-engine in ASP.NET MVC 3 a need occurred for a quick-reference.
Sections - Replacement for asp:ContentPlaceHolder
and asp:Content
Where you the old WebForms view-engine used to use the controls and to dynamically switch out parts of the content on a page, the Razor view-engine uses sections.
_Layout.cshtml
(Equivalent to a .master
-page):
<div>Template content</div>
@RenderBody()
<div>More template content</div>
@RenderSection("OtherContent", required: false)
Page.cshtml
:
@section OtherContent {
<span>Other content goes here</span>
}
<div>Main page-content</div>
In above code the RenderSection
-method in the _Layout.cshtml
renders the content within the matching @section
in the Page.cshtml
. The required
-parameter indicates if the section is required and should throw an exception if the section doesn't exist. The RenderBody
-method renders the rest of the content in the Page.cshtml
, which is not inside any section.
Declaring the ViewModel
In the old WebForms view-engine your declaration of the view-model would look like something like this:
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<MyViewModel>" %>
While in the Razor view-engine declaring your view-model is as easy as this:
@model MyViewModel
Inline C#-code in the HTML
If you wanted to loop over a collection in your view-model in WebForms view-engine your code would look something like this:
<% foreach(var item in Model.Items) { %>
<% if(item.IsValid()) { %>
<div class="<%: item.ClassName %>">&;lt;%: item.Title %></div>
<% } %>
<% } %>
The percent-tags make it a bit hard to quickly get an overview of what is HTML and what is code. This is one of the largest upsides to the Razor view-engine, where the same code would be written much more readable like this:
@foreach(var item in Model.Items) {
if(item.IsValid())
{
<div class="@item.ClassName">@item.Title</div>
}
}
If you make a proper installation of MVC 3 you will get syntax-highlighting in Visual Studio for separating C#-code and HTML-tags.
Advanced inline C#-code
Razor is extremely intelligent when it comes to determining when code starts and ends behind the @-signs, which is very well visualized by the IntelliSense in Visual Studio.
<div>This is @Model.Name's page</div>
Since the apostrophe doesn't follow any pattern that could make it correct C#-code, Razor knows to cut the code from there.
If you want to be extra clear in your code, against other developers, but also against Razor, as to where the code starts and ends, you can use parentheses like this:
<div>This is @(Model.Name)'s page and has the status "@(Model.Status)"!</div>
Inline C#-code for logic
You can include code on the page that is not necessarily written out on the page directly, but handles logic and page-specific functionality. For this you use the @
-sign, followed by curly braces.
<div>Other content</div>
@{
string capitalizedTitle = Model.Title.ToUpper();
}
<h1>Page about @capitalizedTitle</h1>
This is used in the templates that comes with MVC 3 to set which Layout
-file to use. But you can use this on your own for setting the title-text in the title
-tag.
Page.cshtml
:
@{
ViewBag.Title = "Index titel - " + Model.SubTitle;
}
\_Layout.cshtml
:
<head>
<title>@ViewBag.Title</title>
<!-- ... -->
Helpers - Reusing code specific to view-template
With the new @helper-syntax in Razor you can easily write re-usable methods that deals with output-functionality within view-templates.
@helper ShowInfo(string name, bool hasContent) {
if(hasContent) {
<div>This is info about @name.ToUpper()</div>
}
}
Namespaces
Using a namespace is very easy and reminds us a lot of the old way to do it:
@namespace System.ComponentModel.DataAnnotations
Server-side comments
To do server-side comments with Razor you can click the "Comment" toolbar button or press Ctrl+K, Ctrl+C to apply a server-side comment. The commented code is place between a @*
and a *@
and looks like this:
@" This is the text of the model. MUST be HTML-encoded. "@
<div class="special-elemet">@Model.Text</div>
Global settings for view-templates
If you place a file named _ViewStart.cshtml
in the root of the ~/Views
-folder, the Razor-code in this code will be applied as default to all view-templates in the sub-folders. In the templates that comes with MVC 3 this is used to set the default Layout-file to be used for the view-templates.
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
Not HTML-encoding content
In the old WebForms view-engine you could use a colon-character instead of an equals-sign to HTML-encode content like this:
<%= ContentToBeOutputWithoutEncoding %>
<%: ContentToBeEncoded %>
The Razor view-engine automatically HTML-encodes whatever strings you output without explicitly using Html.Raw
-method like this:
@Html.Raw(ContentToBeOutputWithoutEncoding)
The <text>
-tag for Razor
The way Razor analyzes the code to find the start and end only makes it it possible to have one element (with multiple children of course) inside an expression. To resolve this Razor introduces a , where you can nest multiple lines of code:
<text>
<div>One nested item</div>
<span>Another nested item</span>
</text>