Hello MVC world
2.2 Creating your first MVC application
2.2.3 Controllers, actions, and displaying dynamic content
In chapter 1, we explained that the role of a controller is that of a coordinator. It can accept input (via a variety of sources, such as form data or in a URL) but it delegates the rendering of the page to the view.
CONTROLLER CLASSES AND ACTION METHODS
In ASP.NETMVC, controllers are represented as classes that inherit from the Controller base class, where individual methods (known as actions) correspond to individual URLs.
To illustrate how this works, we’ll take a look at our project’s HomeController, which can be found within the Controllers directory. The code for this class is shown in the fol-lowing listing.
Listing 2.1 The default HomeController
Inherits from
The HomeController is a very straightforward implementation of a controller class. To indicate that it is a controller, it inherits from the Controller base class and also has the “Controller” suffix in its name.
The class also contains two action methods. Actions are public methods on a con-troller class that handle requests to particular URLs. In this case, the actions are named Index and About. Because these actions are within the HomeController, they can be accessed at the URLs /Home/Index and /Home/About respectively. So if your application were hosted under the domain MySite.com, then the full URL for the Home action would be http://MySite.com/home/index. If a user were to enter this URL into a browser, an instance of the HomeController class would be instantiated by the framework, and the Index action method would be invoked.
ROUTES—MAPPING URLS TO ACTIONS
At this point, you might be asking how does the framework know how to map URLs to a particular controller action? The answer lies within the Global.asax file’s RegisterRoutesmethod. This method defines routes that map a URL pattern to a controller or action. The implementation of this method is shown next.
public static void RegisterRoutes(RouteCollection routes) {
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional }
The DefaultApi piece is for web API and will be covered in chapter 24. Notice that two entries are defined. The first is an IgnoreRoute, and it basically tells the framework not to worry about anything matching the specified path. In this case, it says not to process any paths containing the .axd file extension, such as Trace.axd. The second entry, MapRoute, defines how URLs are processed. This default route will suffice for a while, but later on you’ll want to add more routes in order to provide URLs that are specific to your application.
■ id—Optional; allows the id to be omitted from the URL Listing 2.2 Registering routes
Because of these default values, you can omit segments from the URL and achieve the same behavior. Again, if your domain were MySite.com, the URLs http://MySite.com/
Home/Index, http://MySite.com/Home and http://MySite.com would all end up invoking the HomeController’s Index action.
Looking back at the HomeController in listing 2.1, the Index action contains two lines of code:
ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";
return View();
The first line assigns some arbitrary text to the ViewBag, while the second indicates to the framework that a view should be rendered.
The ViewBag is essentially a dictionary—it provides a way to store data that can then be accessed from within a view. It uses the dynamic language features of .NET 4 to allow the creation of properties on the fly. For example, you can assign another property to the ViewBag with a single line of code:
public ActionResult Index() {
ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";
ViewBag.CurrentDate = DateTime.Now;
return View();
}
Here we simply assigned the current date and time to a property on the ViewBag called CurrentDate. This property was created on the fly and there was no need to modify a class definition in order to add this property. We can now access this prop-erty from within our view, which is rendered by the call to return View().
The View method (which returns a ViewResult instance) indicates to the frame-work that a view should be rendered. In this case, we haven’t specified the name of the view so the framework will infer that it should attempt to render a view with the same name as the action—Index—which it will attempt to locate within the project’s Views
A note about routing
The route with the template {controller}/{action}/{id} is a generic route that can be used to serve many different web requests. Tokens are denoted by the use of curly braces, {}, and the word enclosed in braces matches a value the MVC Frame-work understands.
The most common values that we’ll be interested in are controller and action.
The controller route value is a special value that the framework passes to a con-troller factory in order to instantiate a concon-troller. This is also the route we’ll be using for the rest of the chapter, so we’ll use a URL in the form of http://mvccontrib.org/
controllername/actionname.
We’ll explore routing in more depth in chapter 9.
directory and then within the subdirectory named after the controller, which in this case is Home.
THE VIEW
If you look back at the project structure in figure 2.5, you’ll see that there is indeed a file named Index.cshtml that resides within the Views/Home subdirectory. If you open this file, you’ll see the following markup as part of Index.cshtml:
@{
ViewBag.Title = "Home Page";
}
@section featured {
<section class="featured">
<div class="content-wrapper">
<hgroup class="title">
<h1>@ViewBag.Title.</h1>
<h2>@ViewBag.Message</h2>
</hgroup>
<p>The current date is @ViewBag.CurrentDate.ToLongDateString()</p>
<p>
The Index view contains a mixture of C# code and HTML markup. The top of the file con-tains a code block that sets the page’s title, and then a message is displayed within an <h2 />
element. The call to @ViewBag.Message writes out the contents of the ViewBag’s Message property that was set in the controller.
You can modify the view to also display
Note that the @ prefix indicates a transition between HTML and code. The end result is shown in figure 2.7.
The default HomeController illustrates the basic use of controllers and views within
Figure 2.7 The contents of our custom ViewBag entry containing the current date is displayed on the page.
an MVC application, but displaying a simple message on the screen isn’t very interest-ing. In the next section we’ll add some interactivity to the application by allowing users to add entries to the guestbook.