Adding a View
In this section we're going to modify the HelloWorldController
class to use a view template file to cleanly encapsulate the process of generating HTML responses to a client.
Let's start by using a view template with the Index
method in the HelloWorldController
class. Currently the Index
method returns a string with a message that is hard-coded within the controller class. Change the Index
method to return a View
object, as shown in the following:
public ActionResult Index() { return View(); }
Let's now add a view template to our project that we can invoke with the Index
method. To do this, right-click inside the Index
method and click Add View.
The Add View dialog box appears. Leave the default entries and click the Add button.
The MvcMovie/Views/HelloWorld folder and the MvcMovie/Views/HelloWorld/Index.cshtml file are created. You can see them in Solution Explorer:
Add some HTML under the <h2>
tag. The modified MvcMovie/Views/HelloWorld/Index.cshtml file is shown below.
@{ ViewBag.Title = "Index"; } <h2>Index</h2> <b>Hello</b> World!
Run the application and browse to the "hello world" controller (http://localhost:xxxx/HelloWorld). The Index
method in your controller didn't do much work; it simply ran the statement return View();
, which indicated that we wanted to use a view template file to render a response to the client. Because we did not explicitly specify the name of the view template file to use, ASP.NET MVC defaulted to using the Index.cshtml view file within the /Views/HelloWorld folder. The image below shows the string hard-coded in the view.
Looks pretty good. However, notice that the browser's title bar says "Index" and the big title on the page says "My MVC Application." Let's change those.
Changing views and layout pages
First, let's change the text "My MVC Application." That text is shared and appears on every page. It actually appears in only one place in our project, even though it's on every page in our application. Go to the /Views/Shared folder in Solution Explorer and open the _Layout.cshtml file. This file is called a layout page and it's the shared "shell" that all other pages use.
Note the @RenderBody()
line of code near the bottom of the file. RenderBody
is a placeholder where all the pages you create show up, "wrapped" in the layout page. Change the <h1>
heading from "My MVC Application" to "MVC Movie App".
<div id="title"> <h1>MVC Movie App</h1> </div>
Run the application and note it now says "MVC Movie App". Click the About link, and that page shows "MVC Movie App", too.
The complete _Layout.cshtml file is shown below:
<!DOCTYPE html> <html> <head> <title>@ViewBag.Title</title> <link href="@Url.Content("/Content/Site.css")" rel="stylesheet" type="text/css" /> <script src="@Url.Content("/Scripts/jquery-1.4.4.min.js")" type="text/javascript"></script> </head> <body> <div class="page"> <div id="header"> <div id="title"> <h1>MVC Movie App</h1> </div> <div id="logindisplay"> @Html.Partial("_LogOnPartial") </div> <div id="menucontainer"> <ul id="menu"> <li>@Html.ActionLink("Home", "Index", "Home")</li> <li>@Html.ActionLink("About", "About", "Home")</li> </ul> </div> </div> <div id="main"> @RenderBody() <div id="footer"> </div> </div> </div> </body> </html>
Now, let's change the title of the Index page (view).
Open MvcMovie/Views/HelloWorld/Index.cshtml. There are two places to make a change: first, the text that appears in the title of the browser, and then in the secondary header (the <h2>
element). We'll make them slightly different so you can see which bit of code changes which part of the app.
@{ ViewBag.Title = "Movie List"; } <h2>My Movie List</h2> <b>Hello</b> World!
Run the application and browse to http://localhost:xx/HelloWorld. Notice that the browser title, the primary heading, and the secondary headings have changed. It's easy to make big changes in your application with small changes to a view. (If you don't see changes in the browser, you might be viewing cached content. Press Ctrl+F5 in your browser to force the response from the server to be loaded.)
Our little bit of "data" (in this case the "Hello World!" message) is hard-coded, though. Our MVC application has V (views) and we've got C (controllers), but no M (model) yet. Shortly, we'll walk through how create a database and retrieve model data from it.
Passing Data from the Controller to the View
Before we go to a database and talk about models, though, let's first talk about passing information from the Controller to a View. We want to pass what a view template requires in order to render an HTML response to a client. These objects are typically created and passed by a controller class to a view template, and they should contain only the data that the view template requires — and no more.
Previously with the HelloWorldController
class, the Welcome
action method took a name
and a numTimes
parameter and then output the parameter values to the browser. Rather than have the controller continue to render this response directly, let's instead put that data in a bag for the View. Controllers and Views can use a ViewBag
object to hold that data. That will be passed over to a view template automatically, and used to render the HTML response using the contents of the bag as data. That way the controller is concerned with one thing and the view template with another — enabling us to maintain clean "separation of concerns" within the application.
Alternatively, we could define a custom class, then create an instance of that object on our own, fill it with data and pass it to the View. That is often called a ViewModel, because it's a custom Model for the View. For small amounts of data, however, the ViewBag works great.
Return to the HelloWorldController.cs file change the Welcome
method inside the controller to put the Message and NumTimes into the ViewBag. The ViewBag is a dynamic object. That means you can put whatever you want in to it. The ViewBag has no defined properties until you put something inside it.
The complete HelloWorldController.cs
with the new class in the same file.
using System.Web.Mvc; namespace MvcMovie.Controllers { public class HelloWorldController : Controller { public ActionResult Index() { return View(); } public ActionResult Welcome(string name, int numTimes = 1) { ViewBag.Message = "Hello " + name; ViewBag.NumTimes = numTimes; return View(); } } }
Now our ViewBag contains data that will be passed over to the View automatically. Again, alternatively we could have passed in our own object like this if we liked:
return View(myCustomObject);
Now we need a WelcomeView
template! Run the application so the new code is compiled. Close the browser, right-click inside the Welcome
method, and then click Add View.
Here's what your Add View dialog box looks like.
Add the following code under the <h2>
element in the new Welcome.cshtml file. We'll make a loop and say "Hello" as many times as the user says we should!
@for (int i=0; i < ViewBag.NumTimes;i++) { <h3>@ViewBag.Message @i.ToString()</h3> }
Run the application and browse to http://localhost:xx/HelloWorld/Welcome?name=Scott&numtimes=4. Now data is taken from the URL and passed to the controller automatically. The controller packages up the data into a ViewBag
object and passes that object to the view. The view than displays the data as HTML to the user.
Well, that was a kind of an "M" for model, but not the database kind. Let's take what we've learned and create a database of movies.