Monthly Archives: June 2009

ASP.NET MVC QuickStart 2: Implement model, controller and view

…continued from part 1.

Objectives

In this Hands-On Lab, you will create functionality to display a list of members. In particular, you will:

  • Create a model
  • Create a controller
  • Create a view

System requirements

You must have the following items to complete this lab:

  • Microsoft Visual Studio 2008 SP1 (professional edition)
  • Microsoft ASP.NET MVC 1.0

Prequisites

You must have the following skills to understand this lab:

  • Fundamental knowledge of software development in .NET 3.5
  • Some experience in ASP.NET web development

This lab builds further on the QuickStart 1 code.

Task 1: create a model

In ASP.NET MVC, the model is responsible for providing the needed data and applying the business logic. Therefore, we will start by creating the model for our web application. We will first create a Member business entity, so right click the Model folder, select Add -> Class and call the new class Member.cs:

Add member

Keep it simple, and define the following properties:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MvcApplication1.Models
{
public class Member
{
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
}

The model is also responsible for data access operations, so add another class to the Model folder and call it MemberService.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MvcApplication1.Models
{
/// <summary>
/// For simplicity, MemberService mimics a member service providing
/// basic member operations and working with mock data.
/// </summary>
public class MemberService
{
private static List<Member> members;
static MemberService()
{
// Create some dummy members
members = new List<Member>();
members.Add(new Member()
{ ID = 0, FirstName = "Geoffrey", LastName = "Denver" });
members.Add(new Member()
{ ID = 1, FirstName = "Todd", LastName = "Lorn" });
members.Add(new Member()
{ ID = 2, FirstName = "Loren", LastName = "Lyle" });
members.Add(new Member()
{ ID = 3, FirstName = "Ralphie", LastName = "Ethan" });
members.Add(new Member()
{ ID = 4, FirstName = "Mervyn", LastName = "Tyler" });
}
public static List<Member> GetMembers()
{
return members;
}
}
}

At this point, we have created a very basic model that we can use to retrieve members.

Task 2: create a controller

The next step is to create a controller that will be responsible for retrieving the member data and passing this data to a view. To do that, right click the Controllers folder, select Add -> Controller and call it MembersController:

Add controller

Click Add. The new file membersController.cs will now be added to the Controllers folder. Modify it as follows:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using MvcApplication1.Models;
namespace MvcApplication1.Controllers
{
public class MembersController : Controller
{
//
// GET: /Members/
public ActionResult Index()
{
// Get a list of members using the model
List<Member> members = MemberService.GetMembers();

// return this list to the default view
return View(members);
}
}
}

Put a breakpoint on the first line of the Index method and hit F5 to debug the web application. The first time you will see the following dialog:

Debugging not enabled

Just click OK because we want to enable debugging, and the web page will appear. Then, modify the URL to trigger the Index action of the MembersController we just created, as follows:

Web page

When you do this, the routing system will map this URL to the Index action method of the Members controller, and so the Index method will execute:
 

MembersController

Hit F5 again, and then you’ll see the following error appear:
 

Server error

This is normal, because the Index action method tries to find the default view Index.aspx in the Views/Members folder, but we didn’t create that view yet.

Task 3: create a view

In this task, we will create a view to display a list of members. To do that, open MembersController.cs and right click the Index method:

Add view

Then select Add View and fill in the required fields as follows:

Add view

Make sure that:

  • The View name is called Index.
  • You check the Create a strongly typed view check box, and set the View data class to MvcApplication1.Models.Member. This way, we will be able to access the member data in the view in a strongly typed way.
  • Select List as the View content. This will generate code that displays a list of members.

Click Add. The view Index.aspx will be generated and added to the Views/Members folder of the project:

<%@ Page Title="" Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<IEnumerable<
MvcApplication1.Models.Member>>"
%>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent"
runat="server">
Index
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent"
runat="server">
<h2>Index</h2>
<table>
<tr>
<th></th>
<th>
ID
</th>
<th>
FirstName
</th>
<th>
LastName
</th>
</tr>
<% foreach (var item in Model) { %>

<tr>
<td>
<%= Html.ActionLink("Edit", "Edit", new {
/* id=item.PrimaryKey */ }) %> |
<%= Html.ActionLink("Details", "Details", new {
/* id=item.PrimaryKey */ })%>
</td>
<td>
<%= Html.Encode(item.ID) %>
</td>
<td>
<%= Html.Encode(item.FirstName) %>
</td>
<td>
<%= Html.Encode(item.LastName) %>
</td>
</tr>

<% } %>
</table>
<p>
<%= Html.ActionLink("Create New", "Create") %>
</p>
</asp:Content>

The view already contains HTML to display the list of members, and the code is very straightforward. Notice:

  • the foreach statement that is used to loop all elements of the Model property. Because we made it a strongly typed view, it inherits from ViewPage<IEnumerable<MvcApplication1.Models.Member>>, and therefore the Model property if of type IEnumerable<MvcApplication1.Models.Member> and thus we can use it in a strongly typed way.
  • The use of Html.ActionLink helper method to generate edit, create and details links. So you don’t have to write links yourself, instead always let ASP.NET MVC generate these for you (it will use routing mechanism to do so).
  • The use of Html.Encode helper method, which encodes HTML to avoid cross-site scripting.

One more thing to do manually: replace the documented code in the action links so that we assign the primary key to each member instance for the Edit and Details links:

<%= Html.ActionLink("Edit", "Edit", new { id=item.ID }) %> |
<%= Html.ActionLink("Details", "Details", new { id=item.ID }) %>

Run the web application again, change the url to http://localhost:3382/members/index and the list of members will be shown:

My MVC application

Note: none of the generated links work at this point, so that’s what we’ll do next.
 
Go to part 3.
Advertisements

ASP.NET MVC QuickStart 1: Introducing ASP.NET MVC

Objectives

In this Hands-On Lab, you will be introduced to the ASP.NET MVC framework. In particular, you will:

  • Understand key benefits of ASP.NET MVC
  • Understand what the MVC design pattern is about
  • Create an ASP.NET MVC application
  • Understand ASP.NET MVC default routing

System requirements

You must have the following items to complete this lab:

  • Microsoft Visual Studio 2008 SP1 (professional edition)
  • Microsoft ASP.NET MVC 1.0

Prequisites

You must have the following skills to understand this lab:

  • Fundamental knowledge of software development in .NET 3.5
  • Some experience in ASP.NET web development

Task 1: Understand key benefits of ASP.NET MVC

Before you begin, you should understand the main advantages of ASP.NET MVC and why it is important to adopt it in most of your projects:

  • MVC design pattern: the ASP.NET MVC framework is a modern MVC implementation
  • Extensibility: the ASP.NET MVC framework consists of a number of independent components that can be completely replaced with your own implementation if needed. Your options are:
    • Use the default implementation
    • Derive a subclass of the default implementation to tweak behavior
    • Replace a component entirely with a new implementation
  • Testability: the ASP.NET MVC framework is made to be tested using today’s testing and mocking frameworks.
  • Full control: no generated HTML that violates standards, because you are in control over the rendered HTML, scripts and markup. This also means that there is no hidden magic going on. As an example, there is no ViewState anymore, so pages are smaller and faster to load.
  • Routing system: ASP.NET MVC works with a powerful routing system that maps search-engine friendly URL’s to actions.
  • Stateless nature: embraces stateless nature of the web instead of trying to hide it and therefore avoiding complex situations.

Task 2: Understand what the MVC pattern is about

ASP.NET MVC is based on the MVC architectural pattern, which stands for Model-View-Controller, and is all about keeping things organized via separation of concerns:

MVC

This means that we have 3 areas of responsibility:

  • Model: contains the business and data logic.
  • View: is responsible for presentation logic, so this is your user interface
  • Controller: contains application logic; here we receive user input and react on it by retrieving data from the model and asking views to render themselves using this data. So the controllers act as a bridge between your model and the user interface.

As an example, if an event occurs (user clicks a button on a web page), then the controller takes action and reacts on this event by using the model to execute business and data logic (retrieving data) and asking a specific view to render itself using this data:

MVC

The goal of this separation is that each area has its own concern and concerns should never be mixed; and as a result it is possible to modify either the visual appearance of the application, the application logic or the underlying business rules without affecting the other.

Task 3: Create an ASP.NET MVC application

In this task you will create and configure an empty ASP.NET MVC application project using the MVC Visual Studio template.

Start Visual Studio 2008. Click File -> New -> Project, click the Web project type and select ASP.NET MVC Web Application. Give your project a name ‘MvcApplication1’ and location and click OK:

Create new MVC project

In a next dialog, you will get the option of creating a unit test project too. For now, check the ‘No, do not create a unit test project’ option and click OK:

Create test project

As a result, the solution and web project will be created, containing some default folders and files, structured to support the MVC pattern:

Visual studio solution

As you see, the most important folders are:

  • Controllers: contains all controller classes.
  • Models: contains all models and underlying business and data logic.
  • Views: contains all views, for example .aspx or .ascx files.
  • Shared: contains all shared views, for example master pages…
  • Scripts: contains all java script files.
  • Content: contains content files, for example images, style sheets…

If you run this, you will see this simple web application:

MVC application

Task 4: Understand ASP.NET MVC default routing

When the user types in a URL, a routing system takes care of mapping this incoming request to a specific action method of a specific controller, using a default naming convention.

This means that a URL in the form of http://localhost, http://localhost/home or http://localhost/home/index all map to an action method called ‘Index’ of a controller called HomeController. We will later see how this routing from URL to controller works and can be modified, but for now just assume that routing takes care using some default naming convention.

The controller HomeController is a normal C# class (inheriting from Controller) that is created in the Controllers folder of the project, and the action Index is a normal C# method in that HomeController class:

public class HomeController : Controller
{
public ActionResult Index()
{
ViewData["Message"] = "Welcome to ASP.NET MVC!";
return View();
}
}

When the Index action method gets executed, it returns a view which has to be rendered. Again, using the default naming convention it knows that it has to render the Index.aspx view in the Views/Home folder of the project:

<%@ 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>

In this case, the controller Index action stores a string in ViewData (which is a built-in loosely typed dictionary) , and because the Index.aspx view has also access to it, this data can be used in the view. So, ViewData is a way to pass data from the controller to the view.

Note: obviously, passing data in a loosely typed way is evil. In the next lab, we will use a strongly typed way to do this!

Go to next part.