# Tuesday, 06 October 2009

The ASP.NET MVC framework (which I will refer to as "MVC" in this article) encourages greater separation of concerns than the older ASP.NET web forms framework.

Some key differences between web forms and  MVC are

  • ASPX pages in MVC have no code-behind files. This discourages developers from putting any business logic in the view.
  • By default, URLs in MVC do not point to a file on disc. Rather, they point to an Action in a Controller.

A controller is a class that inherits from System.Web.Mvc.ControllerBase.

MVC uses several conventions to find this class. First, it expects controller classes to be in the Controllers folder. Also, it expects a controller class name to end with "Controller".  So if we tell MVC to look for a Product controller, it will look for the file Controllers\ProductController.cs or Controllers\ProductController.vb.

An Action is a method within a Controller class that returns a System.Web.Mvc.ActionResult. The ActionResult represents the View data that is available when MVC renders output to the client.

One way we can tell MVC to look for a controller is by typing a URL into the browser’s address bar. Doing this causes MVC to use the routing engine. I described the routing engine in a previous article. The default routing assigned to a new MVC project looks for a URL with the following format

Controller/action/id

When the routing engine encounters a URL formatted like the one above, it looks for a controller named after the first part of the URL; an action method within that controller named after the second part of the URL; and a parameter to pass to that method in the third part of the URL. For example, if the user typed the following URL into the address bar:

Customer/Details/1

, MVC would look for a class named CustomerController in Controller\CustomerController.cs (assuming we are coding in C#). If it found this class, it would look in it for a method named "Details" that returns an ActionResult and that accepts a parameter. It would then call the Details method and pass it the parameter "1".

The ActionResult returned by this method is used by the MVC View engine to render output to the client. I described MVC views in a previous article.

The code below is for a Controller Action method. It assumes the existence of the GetCustomer method that returns a single customer object.

public ActionResult Details(Int32 id)
{
    Customer cust = MVCDemoRepository.GetCustomer(id);
    return View(cust);
}

The View method called in the code above returns a ViewResult – a class that inherits from ActionResult. By passing the Customer object to this method, the ActionResult’s Model property is populated with the Customer object. Properties of that object can then be used within the view.

Another way to pass data from the controller to the view is to populate the ViewData property. ViewData is a list of name-value pairs. You can populate this list in the controller and retrieve elements from it within the view. We can modify the Action method above to add to the ViewData list.

public ActionResult Details(Int32 id)
{
    ViewData["HelloMessage"] = "Good morning to you";
    Customer cust = MVCDemoRepository.GetCustomer(id);
    ViewData["GoodbyeMessage"] = "Good night. See you later";
    return View(cust);
}

By default, this controller routes the user to a view with the same name as the Action in a folder named after the controller. In this case, MVC will look in the \Views\Customer folder for a file named either Details.aspx or Details.ascx. If it cannot find either of these files in that folder, it will search in the Views\Shared folder. Here MVC is using configuration again to determine where to look for files.

You can change the view MVC looks for by using an overload of the View method as in the following example

return View("CustomerDetails", cust); 

The above line tells MVC to look for a view page named CustomerDetails.aspx or CustomerDetails.ascx in either \Views\Customer or \Views\Shared.

Here is a complete listing of a Controller class

using System;
using System.Collections.Generic;
using System.Web.Mvc;
using MVCDemoController.Models;

namespace MVCDemoController.Controllers
{
    public class CustomerController : Controller
    {
        // GET: /Customer/
        public ActionResult Index()
        {
            List<Customer> customers = MVCDemoRepository.GetAllCustomers();
            return View(customers);
        }

        // GET: /Customer/Details/1
        public ActionResult Details(Int32 id)
        {
            ViewData["HelloMessage"] = "Good morning to you";
            Customer cust = MVCDemoRepository.GetCustomer(id);
            ViewData["GoodbyeMessage"] = "Good night. See you later";
            return View(cust);
        }
    }
}

Below is a sample view to render the output from the Details controller action above

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MVCDemoController.Models.Customer>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Details
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <h2>Details</h2>

    <div>
    <%=Html.Encode(ViewData["HelloMessage"]) %>
    </div>
    <fieldset>
        <legend>Fields</legend>
        <p>
            ID:
            <%= Html.Encode(Model.ID) %>
        </p>
        <p>
            FirstName:
            <%= Html.Encode(Model.FirstName) %>
        </p>
        <p>
            LastName:
            <%= Html.Encode(Model.LastName) %>
        </p>
    </fieldset>
    <p>
        <%=Html.ActionLink("Back to List", "Index") %>
    </p>
    <div>
    <%=Html.Encode(ViewData["GoodbyeMessage"]) %>
    </div>

</asp:Content>

Details

Good morning to you
Fields

ID: 1

FirstName: David

LastName: Giard

Back to List

Good night. See you later

The MVC Controller is used to retrieve data from the Model, to populate any extra data needed by the view and to determine which view to render. Understanding it is key to understaning MVC.

Download demo code for this article at MVCDemoController.zip (281.08 KB)

 

ASP.NET | MVC
Saturday, 17 October 2009 12:25:03 (GMT Daylight Time, UTC+01:00)
Enjoying your series on MVC. I may have application for it in mind ;)
David Robbins
Monday, 19 October 2009 14:40:16 (GMT Daylight Time, UTC+01:00)
Thanks Dave. Call me if you need help.
David Giard
Comments are closed.