Exercise 1: Creating a Home Page View Using Razor Syntax
You have been working with ASP.NET C# language and HTML to create controllers and views. In this exercise, you will learn how to create MVC 3 views by using Razor syntax and Razor Layout Pages. In order to do that you will work with MVC Music Store web application to write its Home Page view in Razor.
Razor Layout Pages
A Razor Layout page is the equivalent of an ASP.NET Master Page. It defines the structure of a Web page by using HTML markup, and defines sections that will be filled with custom content. Web pages linked to a layout will only have to complete the sections with their own HTML. By using layout pages your site will have a consistent look that will also be easier to modify.
Razor Layout Pages – Structure
.png)
Figure 1Layout and Web Pages
In essence, Razor Layout pages are HTML files that define a Body and additional sections by using the following instructions:
- @RenderBody(): Renders the content of a page that is not within any named sections.
- @RenderSection("mySectionName"): Renders the content of the section within the given name. Sections are mandatory by default, so each page linked to the template will have to declare them.
- @RenderSection("mySectionName", optional:true): Renders the content of an optional section. The pages that are linked to the template can omit the definition of an optional section.
Note: Optional sections allow us to use the same layout in pages that share part of the structure. However, this feature has to be carefully used if we want to keep a tidy and maintainable layout. In those cases, when the differences between the pages are significant, it will be better to add a new page layout instead of having a complex one.
Next you will see an example of a layout that defines two sections, one of them optional:
<!DOCTYPE html>
<html>
<head>
<title>Layout Page Content</title>
<link href="/Content/Site.css" rel="Stylesheet" type="text/css" />
</head>
<body>
<div id="header">
@RenderSection("header")
@RenderBody()
@RenderSection("footer", optional:true)
</div>
<div id="main">
@RenderSection("header")
@RenderBody()
@RenderSection("footer", optional:true)
</div>
<div id="footer">
@RenderSection("header")
@RenderBody()
@RenderSection("footer", optional:true)
</div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>Layout Page Content</title>
<link href="/Content/Site.css" rel="Stylesheet" type="text/css" />
</head>
<body>
<div id="header">
@RenderSection("header")
@RenderBody()
@RenderSection("footer", optional:=true)
</div>
<div id="main">
@RenderSection("header")
@RenderBody()
@RenderSection("footer", optional:=true)
</div>
<div id="footer">
@RenderSection("header")
@RenderBody()
@RenderSection("footer", optional:=true)
</div>
</body>
</html>
Optional sections can also be defined by using Razor directive
IsSectionDefined("name").
The following line is equival to “
@RenderSection("footer",optional:true)”:
@if (IsSectionDefined("footer")) { @RenderSection("footer") }Here is an example of a Razor Web page that links to the previous layout:
@{
}
@section header {
}
@section footer {
}
LayoutPage = "~/Shared/Site.cshtml";
@{
}
@section header {
}
@section footer {
}
<p>
Razor example
</p>
@{
}
@section header {
}
@section footer {
}
<p>
Optional page footer
</p>
@{
}
@section header {
}
@section footer {
}
<div>
Using Layout Pages – Body content
</div>
@Code
End Code
@Section header
@ Section footer
LayoutPage = "~/Shared/Site.vbhtml"
@Code
End Code
@Section header
@ Section footer
<p>
Razor example
</p>
End Section
@Code
End Code
@Section header
@ Section footer
<p>
Optional page footer
</p>
End Section
<div>
Using Layout Pages – Body content
</div>
Most of the HTML elements were moved to the layout, leaving only the body and the section declarations.
Task 1 – Creating a CSHTML|VBHTML Layout Page
In this task, you will learn how to create a Layout page for Razor views that will work like the Site.master page from the ASP.NET MVC Fundamentals Hands-on Lab exercises.
- If not already open, start Microsoft Visual Web Developer 2010 Express from Start | All Programs | Microsoft Visual Studio 2010 Express | Microsoft Visual Web Developer 2010 Express.
- In the File menu, choose Open Project. In the Open Project dialog, browse to Source\Ex01-CreatingAHomeRazorView\Begin, select MvcMusicStore.sln and click Open.
- Add a Layout Page. Because it is a shared resource you will create it under the /Views/Shared folder, in the same place of ASP.NET MasterPage. To do this, expand the Views folder and right-click the Shared folder. Select Add and then the New Item command.
.png)
Figure 2Adding a new item to the solution
- In the Add New Item dialog box, select the MVC 3 Layout Page (Razor) template, located under Visual [C#|Basic], Web template list. Change the name to Site.cshtml|vbhtml and click Add.
.png)
Figure 3Adding a new Razor Layout Page – C#
.png)
Figure 4Adding a new Razor Layout Page - VB
- Site.cshtml|vbhtml file is added. This template contains the HTML layout for all pages on the site. It includes the <html> element for the HTML response, as well as the <head> and <body> elements.
<!DOCTYPE html>
<html>
<head>
<title>@ViewBag.Title</title>
</head>
<body>
<div>
@RenderBody()
</div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>@ViewBag.Title</title>
</head>
<body>
<div>
@RenderBody()
</div>
</body>
</html>
This is the standard layout page generated by MVC 3, which displays the body inside a <div> block.
@ViewBag.Title (equivalent of @ViewBag [“Title”] used in ASP.NET to access ViewBag collection) shows the content of “Title” element.
As
@ViewBag refers to dynamic type collection, it is possible to assign any type of elements inside.
- Add a reference to Mvc MusicStore stylesheet, to define the style of your site.
<!DOCTYPE html>
<html>
<head>
<link href="/Content/Site.css" rel="Stylesheet" type="text/css" />
<title>@ViewBag.Title</title>
</head>
<body>
<div>
@RenderBody()
</div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<link href="/Content/Site.css" rel="Stylesheet" type="text/css" />
<title>@ViewBag.Title</title>
</head>
<body>
<div>
@RenderBody()
</div>
</body>
</html>
- Add a common header with links to the Home page and Store area on all pages in the site. In order to do that, add the following code inside the <div> statement.
<!DOCTYPE html>
<html>
<head>
<link href="/Content/Site.css" rel="Stylesheet" type="text/css" />
<title>@ViewBag.Title</title>
</head>
<body>
<div>
<div id="header">
<h1>ASP.NET MVC MUSIC STORE</h1>
<ul id="navlist">
<li class="first"><a href="/" id="current">Home</a></li>
<li><a href="/Store/">Store</a></li>
</ul>
</div>
@RenderBody()
</div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<link href="/Content/Site.css" rel="Stylesheet" type="text/css" />
<title>@ViewBag.Title</title>
</head>
<body>
<div>
<div id="header">
<h1>ASP.NET MVC MUSIC STORE</h1>
<ul id="navlist">
<li class="first"><a href="/" id="current">Home</a></li>
<li><a href="/Store/">Store</a></li>
</ul>
</div>
@RenderBody()
</div>
</body>
</html>
- Add an optional section before the body by using IsSectionDefined directive:
…
</div>
@if (IsSectionDefined("header")) {
@RenderSection("header")
}
@RenderBody()
</div>
…
</div>
@If IsSectionDefined("header") Then
@RenderSection("header")
End if
@RenderBody()
</div>
Optional sections can also be defined by using the directive @RenderSection(“header”,optional:true)
Task 2 – Adding a View Template in Razor
In this task, you will add a view template in Razor for the Home page. At the end of the task you should get the same page you use to have when using ASPX templates, but with a simplified syntax.
- Open HomeController.[cs|vb] class and right-click inside the Index Action method display context menu. Select Add View menu option to display the dialog box.
.png)
Adding a new Home Index View from a Razor Template - CS
.png)
Figure 6Adding a new Home Index View from a Razor Template - VB
- The Add View Dialog appears. It allows generating View template files. By default this dialog pre-populates the name of the View template so that it matches the action method that will use it (in this case, View name is set to Index). Fill the dialog box according to the following values and click Add:
- Choose Razor (CSHTML|VBHTML) at “View Engine”.
- Make sure the “Use a layout or master page” checkbox is checked and verify that Razor Layout template path is “~/Views/Shared/Site.cshtml|vbhtml”.
.png)
Figure 7Adding a new Razor View dialog box – C#
.png)
Figure 8Adding a new Razor View dialog box - VB
- Visual Studio generates an Index.cshtml|vbhtml Razor view template inside the Views\Home folder with this structure:
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/Site.cshtml";
}
<h2>Index</h2>
@Code
ViewBag.Title = "Index"
Layout = "~/Views/Shared/Site.vbhtml"
End Code
<h2>Index</h2>
You can change your page layout by modifying the Layout variable value.
- Add a comment and a title inside a code block with Razor syntax.
@{
ViewBag.Title = "Home";
}
<h2>This is the Home Page</h2>
@{
var myname = "MVC Music Store";
<div>
My name is @myname
</div>
}
@*
<div>
I'm inside a comment
</div>
*@
Layout = "~/Views/Shared/Site.cshtml";
@{
ViewBag.Title = "Home";
}
<h2>This is the Home Page</h2>
@{
var myname = "MVC Music Store";
<div>
My name is @myname
</div>
}
@*
<div>
I'm inside a comment
</div>
*@
@Code
ViewBag.Title = "Home"
End Code
<h2>This is the Home Page</h2>
@Code
Dim myname = "MVC Music Store"
<div>
My name is @myname
</div>
End Code
@*
<div>
I'm inside a comment
</div>
*@
Layout = "~/Views/Shared/Site.vbhtml"
@Code
ViewBag.Title = "Home"
End Code
<h2>This is the Home Page</h2>
@Code
Dim myname = "MVC Music Store"
<div>
My name is @myname
</div>
End Code
@*
<div>
I'm inside a comment
</div>
*@
If you have an HTML markup inside a code block (in this example, <div>) and want to use C# code instruction inside, you will need to use the @ operator. After the HTML markup is closed (in this example , </div>), you can continue writing C# code again without using @.
- Show current date after the title, and use @: delimiter to write a variable inside a code block:
@{
}
@{
var now = DateTime.Now;
<text>
Now is @now
</text>
}
<div>
@{
var engine = "Razor";
@: I'm using @engine engine.
}
</div>
ViewBag.Title = "Home";
Layout = "~/Views/Shared/Site.cshtml";
@{
}
@{
var now = DateTime.Now;
<text>
Now is @now
</text>
}
<div>
@{
var engine = "Razor";
@: I'm using @engine engine.
}
</div>
<h2>This is the Home Page</h2>
@{ var myname = "MVC Music Store";
<div>
My name is @myname
</div>
}
@{
}
@{
var now = DateTime.Now;
<text>
Now is @now
</text>
}
<div>
@{
var engine = "Razor";
@: I'm using @engine engine.
}
</div>
@*
<div>
I'm inside a comment
</div>
*@
@Code
End Code
@Code
Dim now = DateTime.Now
<text>
Now is @now
</text>
End Code
<div>
@Code
Dim engine = "Razor"
@: I'm using @engine engine.
End Code
</div>
ViewBag.Title = "Home"
Layout = "~/Views/Shared/Site.vbhtml"
@Code
End Code
@Code
Dim now = DateTime.Now
<text>
Now is @now
</text>
End Code
<div>
@Code
Dim engine = "Razor"
@: I'm using @engine engine.
End Code
</div>
<h2>This is the Home Page</h2>
@Code
Dim myname = "MVC Music Store"
<div>
My name is @myname
</div>
End Code
@Code
End Code
@Code
Dim now = DateTime.Now
<text>
Now is @now
</text>
End Code
<div>
@Code
Dim engine = "Razor"
@: I'm using @engine engine.
End Code
</div>
@*
<div>
I'm inside a comment
</div>
*@
@: operator allows
single lines that can contain
plain text or any mixture of text, markup and code that starts with plain text.
@: must be used once per line.
To write multiple plain text/mixed lines, use the HTML element
<text></text> instead.
Note that is not necessary to use
@: inside a code block if you won’t be starting with plain text. As you have seen before, HTML markup elements can be included at any part of the code.
- Add the optative section “Header”, which was defined in the layout page. This will render a “Welcome” message before the body section:
@{
}
@section header {
<h3>Welcome</h3>
}
ViewBag.Title = "Home";
Layout = "~/Views/Shared/Site.cshtml";
@{
}
@section header {
<h3>Welcome</h3>
}
<h2>This is the Home Page</h2>
…
@Code
End Code
@Section header
<h3>Welcome</h3>
End Section
ViewBag.Title = "Home"
Layout = "~/Views/Shared/Site.vbhtml"
@Code
End Code
@Section header
<h3>Welcome</h3>
End Section
<h2>This is the Home Page</h2>
…
Task 3 – Running the Application
- Press F5 to run the application.
- The project starts in the Home page. Verify that the Razor view is loaded:
.png)
Figure 9Showing a Razor View
Task 4 – Passing Parameters to a Layout Page
In this task, you will learn how to pass parameters from a page to its layout. To do that, you will use the PageData dynamic collection to pass a string message that will be rendered in the layout.
- Open Index.cshtml|vbhtml view from the folder \Views\Home, and assign a string value to PageData collection:
@{
PageData["ApplicationTitle"]= "ASP.NET MVC 3 MUSIC STORE – Razor Style";
}
ViewBag.Title = "Home";
Layout = "~/Views/Shared/Site.cshtml";
@{
PageData["ApplicationTitle"]= "ASP.NET MVC 3 MUSIC STORE – Razor Style";
}
…
@Code
PageData("ApplicationTitle")= "ASP.NET MVC 3 MUSIC STORE – Razor
Style"
End Code
ViewBag.Title = "Home";
Layout = "~/Views/Shared/Site.vbhtml"
@Code
PageData("ApplicationTitle")= "ASP.NET MVC 3 MUSIC STORE – Razor
Style"
End Code
…
- Open Site.cshtml|vbhtml layout page from \Views\Shared project folder, and modify it to show PageData ApplicationTitle element after the @RenderBody directive:
…
@RenderBody()
@if (PageData["ApplicationTitle"]!=null) {
<h3>@PageData["ApplicationTitle"]</h3>
}
…
…
@RenderBody()
@If PageData("ApplicationTitle") IsNot Nothing Then
<h3>@PageData["ApplicationTitle"]</h3>
End if
…
Task 5 – Running the Application
- Press F5 to run the application.
- The project starts in the Home page. Verify that the Razor view is loaded showing the PageData text:
.png)
Figure 10A Razor View Showing a PageData element
In the next exercise you will learn how to create more Razor views that will access to Music Store model and show content.
Next Step
Exercise 2: Using Models in Razor Views