Home is the name of the Controller, and ASP.NET MVC appends Controller to the URL name, looking for the HomeController class, shown in Listing 9-1, physically located in the Controller f
Trang 1You can change your VS Web server’s port number If you open your project’s property
page by right-mouse clicking on the project in Solution Explorer and select Properties,
then select the Web tab on the left, under Servers, you can specify a specific port or
make other Web server choices.
For ASP.NET MVC, the important part of the URL is /Home/About Home is the name of the Controller, and ASP.NET MVC appends Controller to the URL name, looking for the HomeController class, shown in Listing 9-1, physically located in the Controller folder, which is why it’s important to ensure you create files in the proper locations About
is an action, which corresponds to the About method shown in Listing 9-1 Similar to the
About method, the Index action is run through the following URL:
http://localhost:1042/Home/Index
In a later section of this chapter, you’ll learn how ASP.NET MVC performs routing, which maps URLs to Controllers
Both the Index and About actions in Listing 9-1 invoke a method named View This is
a convention for invoking a View with the same name as the action method For example,
calling View in the Index action will show a View named Index, and the call to View in the
About method will show a View named About
One more item to point out is how the Index action assigns a string to a collection called ViewData The ViewData collection is one way for a Controller to pass Model data
to a View I’ll cover more on Controllers, including how to create your own, in a later part
of this chapter, but now, let’s do a quick review of Views so that you can see what happens when they are invoked by the Controller
Displaying Views
A View is what displays in the browser and allows interaction with the user The View can display any information that a Controller passes to it For example, notice that the Index action in Listing 9-1 assigns a string “Welcome to ASP.NET MVC!” with the “Message” key in the ViewData collection
Looking Inside a View
Figure 9-3 shows the View in the browser, displaying the message Listing 9-2 shows the Hypertext Markup Language (HTML) of the View displaying the message The View actually has a combination of HTML and ASP.NET markup, sometimes referred to as ASPX, but I’ll refer to it as just HTML for the rest of the chapter
Trang 2Listing 9-2 A View’s HTML
<%@ Page Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage" %>
<asp:Content ID="indexTitle"
ContentPlaceHolderID="TitleContent"
runat="server">
Home Page
</asp:Content>
<asp:Content ID="indexContent"
ContentPlaceHolderID="MainContent"
runat="server">
<h2><%= Html.Encode(ViewData["Message"]) %></h2>
<p>
To learn more about ASP.NET MVC visit
<a href="http://asp.net/mvc"
title="ASP.NET MVC Website">
http://asp.net/mvc
</a>
</p>
</asp:Content>
A quick overview of Listing 9-2 shows that there is a Page directive with a couple of
Content containers The Page directive specifies a MasterPage and Inherits attributes
A MasterPage is a separate file that holds common HTML that can be shown on all pages
of a site You’ll see how the MasterPage works soon, but let’s stay focused on the current
file in Listing 9-2 until then ASP.NET MVC will compile this HTML into code behind the
scenes, and the generated code will derive from the class defined by the Inherits attribute
The first Content container can hold metadata that goes into an HTML header The
second Content container has the information that will display on the screen Notice
the Html.Encode(ViewData["Message"]) inside of binding tags <%= and %> Any time
you add code or need to access ViewData that was passed by the Controller, you will
use the binding tags Encode is one of several helper methods of the Html class, more
of which you’ll see soon The purpose of Encode is to translate HTML tags into their
encoded representations for security purposes, ensuring that you don’t show any harmful
JavaScript, or other markup that could possibly execute, to the user ViewData["Message"]
should be familiar, as it was set in the Index action in Listing 9-2 but is now being read
and displayed on the screen by this View
Trang 3Organizing View Files
The file structure in Figure 9-2 shows that Views appear in the Views folder and have a
*.aspx file extension Each subfolder under the Views folder corresponds to a Controller, and the Views within the subfolder correspond generally to Controller actions When
a Controller passes control to a View, by calling View, ASP.NET MVC searches for the
View in the Views folder with the subfolder named the same as the Controller and the file named the same as the action calling the View
Notice that there is a Shared folder Sometimes, you’ll want to have a View that is shared by two or more Controller actions, and you can put these shared Views in the Shared subfolder Whenever ASP.NET MVC doesn’t find a View in the Controller-named subfolder, it will search for the View in the Shared folder An important file in the Shared subfolder is the MasterPage, which is discussed next
Assigning MasterPage Files
Most sites on the Web have multiple pages, each with common elements They all have the same header, menu, sidebars, and footers When you first build a site, you can duplicate this common content with no trouble, but this copy-and-paste type duplication will cause
a lot of headaches in the future The first time you have to change the common elements, you’ll need to visit every page If the site has only a few pages, no problem, but the reality
is that most sites of any success grow to dozens or hundreds of pages It is beyond practical
to try to update every page on a site every time the common content changes
This is where MasterPages help, allowing you to specify the common content in one place where you can have content pages that use the MasterPage Whenever something changes in the common content, you update the MasterPage, and every page of a site that uses the MasterPage is automatically updated Listing 9-3 shows the MasterPage, created
by ASP.NET MVC, that the content page in Listing 9-2 uses
Listing 9-3 A MasterPage
<%@ Master Language="C#"
Inherits="System.Web.Mvc.ViewMasterPage" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
Trang 4<title>
<asp:ContentPlaceHolder ID="TitleContent"
runat="server" />
</title>
<link href=" / /Content/Site.css"
rel="stylesheet" type="text/css" />
</head>
<body>
<div class="page">
<div id="header">
<div id="title">
<h1>My MVC Application</h1>
</div>
<div id="logindisplay">
<% Html.RenderPartial("LogOnUserControl"); %>
</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">
<asp:ContentPlaceHolder ID="MainContent" runat="server" />
<div id="footer">
</div>
</div>
</div>
</body>
</html>
Trang 5Moving from the top of Listing 9-3 down, you can see the MasterPage directive at the top
of the page, which states that this is a MasterPage and ASP.NET MVC will handle the page appropriately The DTD is a tag that specifies what Web standards this page supports, which
is read by browsers to help them determine the best way to display the page
The rest of the page is framed inside of HTML tags and ASP.NET MVC markup The
html tag states that this is an HTML document HTML documents have two parts, a head and a body, where the head is for metadata describing the page and the body contains display content
In HTML, a div tag blocks off a chunk of HTML and is useful for layout and organization
of the page The Hx tags, where x is a number between 1 and 6, describe headers, where h1 is
the largest and h6 is the smallest
The ContentPlaceHolder controls are instrumental to the success of the MasterPage If you look at the Content tags in Listing 9-2, you’ll see that they have a ContentPlaceHolderID that matches the ID attributes of the ContentPlaceHolder controls in Listing 9-3 What this means is that when the View renders, the MasterPage will display and ASP.NET MVC will inject the Content regions of the content pages into the matching ContentPlaceHolders of the MasterPage ASP.NET MVC knows which MasterPage to use because the Page directive, as shown in Listing 9-2, specifies the MasterPage attribute
If you recall from the last section, Listing 9-2 had a binding expression for the Html
Encode helper method The MasterPage in Listing 9-3 introduces a couple more Html helper methods, RenderPartial and ActionLink.
The ActionLink method has three parameters: id, controller, and action When the
ActionLink renders in the browser, it will transform into an anchor tag, a, with an id specified in the first parameter of ActionLink When the user clicks the link in the browser, the application will navigate to the Controller in the third parameter of ActionLink and invoke the action in the second parameter of ActionLink So, if the user clicked the link produced by ActionLink("About", "About", "Home"), ASP.NET MVC will invoke the About action of the Home Controller The next section discusses RenderPartial in more detail.
Partial Views (a.k.a User Controls)
It’s often the case that you’ve written View content on one page and need the same identical content on two or more pages As explained with MasterPages, you want to avoid the maintenance work that comes with updating all of the content that is the same on multiple pages While MasterPages are good for content that decorates pages across an entire site, a Partial View is ideal for limited reuse of View content on different pages of a site
Trang 6A good example of where a Partial View is useful is illustrated in the code produced
by the ASP.NET MVC Project Wizard, where it created the LogonUserControl.ascx The
terms Partial View and User Control are synonymous, where the term User Control is
familiar to developers who have worked with previous versions of ASP.NET Web Forms
Partial View is consistent with the ASP.NET MVC perspective of Views, where a Partial
View is not an entire View, but a chunk of View content that can be reused with multiple
Views It isn’t coincidence that this control is physically located in the Views Shared
folder, considering that it can be used on multiple pages Remember, if ASP.NET MVC
can’t find a file in a View folder named after a Controller, it will look in the Shared folder Listing 9-4 shows the contents of LogonUserControl.ascx
Listing 9-4 Contents of a Partial View
<%@ Control Language="C#"
Inherits="System.Web.Mvc.ViewUserControl" %>
<%
if (Request.IsAuthenticated) {
%>
Welcome <b><%= Html.Encode(Page.User.Identity.Name) %></b>!
[ <%= Html.ActionLink("Log Off", "LogOff", "Account") %> ]
<%
}
else {
%>
[ <%= Html.ActionLink("Log On", "LogOn", "Account") %> ]
<%
}
%>
The Control directive at the top of Listing 9-4 indicates that this is a Partial View
Within the control, you can see an if statement, where the language syntax is surrounded
by <% and %> binding symbols The additional syntax to separate code from markup
might take a little getting used to, but it is typical in an MVC application to control how
markup is rendered The IsAuthenticated property of the Request object tells whether
the current user is logged in, and the logic ensures the appropriate message displays
The ActionLink Html helper methods generate action tags with a URL for actions on the
Account Controller We’ve barely touched on routing and how a URL matches controllers
and actions, but the next section explains how routes work in greater depth
Trang 7Managing Routing
ASP.NET MVC has a routing system that matches URLs to controllers with actions and the parameters passed to those actions When you start a new ASP.NET MVC project, default routing will be established via a file called Global.asax, which is where many events affecting the application are placed When you run an ASP.NET MVC application,
it will use URLs of the form http://domain/controller/action/param1/param2/…/paramN? optionalArg=optionalVal Here’s an example:
http://localhost:1042/Home/About
In this example, localhost:1042 is the domain, Home is the Controller, and About is the action When ASP.NET MVC sees this URL, it will instantiate the HomeController class
and call the About method.
The Global.asax file has an Application_Start event that is called the first time the application runs This is where routing is set up so that it will be in place for all of the requests while the application is running Listing 9-5 shows the default routing for an ASP .NET MVC project
Listing 9-5 Setting up routing
C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
namespace MyShopCS
{
// Note: For instructions on enabling IIS6 or IIS7 classic mode, // visit http://go.microsoft.com/?LinkId=9394801
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterRoutes(RouteCollection routes) {
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters new {
Trang 8controller = "Home",
action = "Index",
id = "" } // Parameter defaults
);
}
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
}
}
}
VB:
' Note: For instructions on enabling IIS6 or IIS7 classic mode,
' visit http://go.microsoft.com/?LinkId=9394802
Public Class MvcApplication
Inherits System.Web.HttpApplication
Shared Sub RegisterRoutes(ByVal routes As RouteCollection)
routes.IgnoreRoute("{resource}.axd/{*pathInfo}")
' MapRoute takes the following parameters, in order:
' (1) Route name
' (2) URL with parameters
' (3) Parameter defaults
routes.MapRoute( _
"Default", _
"{controller}/{action}/{id}", _
New With
{
controller = "Home", action = "Index", id = ""
}
)
End Sub
Sub Application_Start()
AreaRegistration.RegisterAllAreas()
RegisterRoutes(RouteTable.Routes)
End Sub
End Class
Trang 9Listing 9-5 shows that the Application_Start event invokes a method named
RegisterRoutes, passing the Routes property of the RouteTable class The Routes property is
a static RouteCollection, meaning that there is only one copy for the entire application, and
it will hold multiple routes When the application starts, this collection will be empty and
the RegisterRoutes method will populate the collection with routes for this application.
Routing works by pattern matching, which you can see through the two statements
in the RegisterRoutes method: IgnoreRoute and MapRoute IgnoreRoute is useful for
situations where you want to let IIS request the exact URL In this case, it is any file with the *.axd extension, regardless of parameters
The MapRoute method shows a common pattern for matching URLs to controllers,
actions, and parameters The first parameter is the name of the route The second
parameter describes the pattern, where each pattern match is defined between curly braces Based on the URL, http://localhost:1042/Home/About, the pattern, {controller}/{action}/ {id}, matches Home to {controller} and About to {action}; there is no match for {id} Therefore, ASP.NET MVC will append “Controller” to the URL segment that matches
{controller}, meaning that the Controller name to instantiate is HomeController About
is the method inside of HomeController to invoke Since About doesn’t have parameters,
supplying the {id} is unnecessary
The third parameter for MapRoute specifies default values, where the key matches the
pattern parameter and the value assigned to the key is what ASP.NET MVC uses when it doesn’t find a pattern match with the URL Here are a couple of examples:
● http://localhost:1042 invokes the Index method of HomeController because no Controller
or action matches and the defaults are Home for {controller} and Index for {action}
● http://localhost:1042/Home invokes the Index method of HomeController because no
action was specified and the default value for {action} is Index
You can create your own custom route by using the MapRoute method and specifying
other default values for the parameters
Building a Customer Management Application
Now, we’ll pull together the ASP.NET MVC concepts you’ve learned and describe how
to build a very simple application that displays, adds, modifies, and deletes customers
In so doing, you’ll see how to build up a Model that supports customers, how to create a custom Controller with actions for managing customers, and how to create multiple views
to handle interaction with the users as they work with customers