Your First ASP.NET MVC Application

Exclusive offer: get 80% off this eBook here
ASP.NET MVC 1.0 Quickly

ASP.NET MVC 1.0 Quickly — Save 80%

Design, develop, and test powerful and robust web applications with MVC framework the agile way

₨120.00    ₨24.00
by Maarten Balliauw | March 2009 | .NET Microsoft

When downloading and installing the ASP.NET MVC framework SDK, a new project template is installed in Visual Studio—the ASP.NET MVC project template. This article by Maarten Balliauw describes how to use this template. We will briefly touch all aspects of ASP.NET MVC by creating a new ASP.NET MVC web application based on this Visual Studio template. Besides view, controller, and model, new concepts including ViewData—a means of transferring data between controller and view, routing—the link between a web browser URL and a specific action method inside a controller, and unit testing of a controller are also illustrated in this article.

(For more resources on .NET, see here.)

Creating a new ASP.NET MVC web application project

Before we start creating an ASP.NET MVC web application, make sure that you have installed the ASP.NET MVC framework SDK from http://www.asp.net/mvc. After installation, open Visual Studio 2008 and select menu option File | New | Project. The following screenshot will be displayed. Make sure that you select the .NET framework 3.5 as the target framework. You will notice a new project template called ASP.NET MVC Web Application. This project template creates the default project structure for an ASP.NET MVC application.

Your First ASP.NET MVC Application

After clicking on OK, Visual Studio will ask you if you want to create a test project. This dialog offers the choice between several unit testing frameworks that can be used for testing your ASP.NET MVC application.

Your First ASP.NET MVC Application

You can decide for yourself if you want to create a unit testing project right now—you can also add a testing project later on. Letting the ASP.NET MVC project template create a test project now is convenient because it creates all of the project references, and contains an example unit test, although this is not required. For this example, continue by adding the default unit test project.

What's inside the box?

After the ASP.NET MVC project has been created, you will notice a default folder structure. There's a Controllers folder, a Models folder, a Views folder, as well as a Content folder and a Scripts folder. ASP.NET MVC comes with the convention that these folders (and namespaces) are used for locating the different blocks used for building the ASP.NET MVC framework. The Controllers folder obviously contains all of the controller classes; the Models folder contains the model classes; while the Views folder contains the view pages. Content will typically contain web site content such as images and stylesheet files, and Scripts will contain all of the JavaScript files used by the web application. By default, the Scripts folder contains some JavaScript files required for the use of Microsoft AJAX or jQuery.

Your First ASP.NET MVC Application

Locating the different building blocks is done in the request life cycle. One of the first steps in the ASP.NET MVC request life cycle is mapping the requested URL to the correct controller action method. This process is referred to as routing. A default route is initialized in the Global.asax file and describes to the ASP.NET MVC framework how to handle a request. Double-clicking on the Global.asax file in the MvcApplication1 project will display the following code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace MvcApplication1
{
public class GlobalApplication : 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 { controller = "Home", action = "Index",
id = "" } // Parameter defaults
);

}

protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
}
}
}

In the Application_Start() event handler, which is fired whenever the application is compiled or the web server is restarted, a route table is registered. The default route is named Default, and responds to a URL in the form of http://www.example.com/{controller}/{action}/{id}. The variables between { and } are populated with actual values from the request URL or with the default values if no override is present in the URL. This default route will map to the Home controller and to the Index action method, according to the default routing parameters. We won't have any other action with this routing map.

By default, all the possible URLs can be mapped through this default route. It is also possible to create our own routes. For example, let's map the URL http://www.example.com/Employee/Maarten to the Employee controller, the Show action, and the firstname parameter. The following code snippet can be inserted in the Global.asax file we've just opened. Because the ASP.NET MVC framework uses the first matching route, this code snippet should be inserted above the default route; otherwise the route will never be used.

routes.MapRoute(
"EmployeeShow", // Route name
"Employee/{firstname}", // URL with parameters
new { // Parameter defaults
controller = "Employee",
action = "Show",
firstname = ""
}
);

Now, let's add the necessary components for this route. First of all, create a class named EmployeeController in the Controllers folder. You can do this by adding a new item to the project and selecting the MVC Controller Class template located under the Web | MVC category. Remove the Index action method, and replace it with a method or action named Show. This method accepts a firstname parameter and passes the data into the ViewData dictionary. This dictionary will be used by the view to display data.

The EmployeeController class will pass an Employee object to the view. This Employee class should be added in the Models folder (right-click on this folder and then select Add | Class from the context menu). Here's the code for the Employee class:

namespace MvcApplication1.Models
{
public class Employee
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
}
}

After adding the EmployeeController and Employee classes, the ASP.NET MVC project now appears as shown in the following screenshot:

Your First ASP.NET MVC Application

The EmployeeController class now looks like this:

using System.Web.Mvc;
using MvcApplication1.Models;

namespace MvcApplication1.Controllers
{
public class EmployeeController : Controller
{
public ActionResult Show(string firstname)
{
if (string.IsNullOrEmpty(firstname))
{
ViewData["ErrorMessage"] = "No firstname provided!";
}
else
{
Employee employee = new Employee
{
FirstName = firstname,
LastName = "Example",
Email = firstname + "@example.com"
};

ViewData["FirstName"] = employee.FirstName;
ViewData["LastName"] = employee.LastName;
ViewData["Email"] = employee.Email;
}

return View();
}
}
}

The action method we've just created can be requested by a user via a URL—in this case, something similar to http://www.example.com/Employee/Maarten. This URL is mapped to the action method by the route we've created before.

By default, any public action method (that is, a method in a controller class) can be requested using the default routing scheme. If you want to avoid a method from being requested, simply make it private or protected, or if it has to be public, add a [NonAction] attribute to the method.

Note that we are returning an ActionResult (created by the View() method), which can be a view-rendering command, a page redirect, a JSON result, a string, or any other custom class implementation inheriting the ActionResult that you want to return. Returning an ActionResult is not necessary. The controller can write content directly to the response stream if required, but this would be breaking the MVC pattern—the controller should never be responsible for the actual content of the response that is being returned.

Next, create a Show.aspx page in the Views | Employee folder. You can create a view by adding a new item to the project and selecting the MVC View Content Page template, located under the Web | MVC category, as we want this view to render in a master page (located in Views | Shared). There is an alternative way to create a view related to an action method, which will be covered later in this article.

In the view, you can display employee information or display an error message if an employee is not found.

Add the following code to the Show.aspx page:

<%@ Page Title="" Language="C#" 
MasterPageFile="~/Views/Shared/Site.Master"
AutoEventWireup="true" Inherits=" System.Web.Mvc.ViewPage" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<% if (ViewData["ErrorMessage"] != null) { %>

<h1><%=ViewData["ErrorMessage"]%></h1>

<% } else { %>

<h1><%=ViewData["FirstName"]%> <%=ViewData["LastName"]%></h1>
<p>
E-mail: <%=ViewData["Email"]%>
</p>

<% } %>
</asp:Content>

If the ViewData, set by the controller, is given an ErrorMessage, then the ErrorMessage is displayed on the resulting web page. Otherwise, the employee details are displayed.

Press the F5 button on your keyboard to start the development web server. Alter the URL in your browser to something ending in /Employee/Your_Name_Here, and see the action method and the view we've just created in action.

Your First ASP.NET MVC Application

ASP.NET MVC 1.0 Quickly Design, develop, and test powerful and robust web applications with MVC framework the agile way
Published: March 2009
eBook Price: ₨120.00
Book Price: ₨300.00
See more
Select your format and quantity:

 

Strong-typed ViewData

In the previous example, we used the ViewData dictionary to pass data from the controller to the view. When developing the view, each dictionary item we want to display should be cast to the correct class, resulting in a less maintainable situation. It might also lead to code spaghetti in the view. It would be useful if the ViewData dictionary already knew which class type each of its items represented. This is where the model comes in handy! We are serving employee information to the view, so why not use the Employee class that we'd previously created as a "the" model for our view? Note that we'd already placed the Employee class inside the Model folder, which is the appropriate location for model classes.

Views can be made strong-typed by updating the view and replacing the base class of the page (System.Web.Mvc.ViewPage) with a generic version: System.Web.Mvc.ViewPage<Employee>. Make sure you compile your project after updating the first few lines of code in the Show.aspx file:

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

By applying the above code, the page's ViewData object will be made generic. This means that the ViewData object will not only be a dictionary, but will also contain a property named Model, which is of the type that has just been passed in: MvcApplication1.Models.Employee.

This ViewData.Model property is also available as a Model property in the view. We will have to update the view to be able to use this new property. Simply change from ViewData[key] to a property Model (which contains the Employee instance). For example, Model.FirstName is in fact the FirstName property of the Employee instance that you want to render. Note that you can still use dictionary entries combined with this strong-typed model.

<%@ Page Title="" 
Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
AutoEventWireup="true"
Inherits=" System.Web.Mvc.ViewPage
<MvcApplication1.Models.Employee>" %>
<asp:Content ID="Content1"
ContentPlaceHolderID="MainContent"
runat="server">
<% if (ViewData["ErrorMessage"] != null) { %>

<h1><%=ViewData["ErrorMessage"]%></h1>

<% } else { %>

<h1><%=Model.FirstName%> <%=ViewData.Model.LastName%></h1>
<p>
E-mail: <%=Model.Email%>
</p>

<% } %>
</asp:Content>

Before being able to run the application, the controller needs some updates as well. The main difference is that employee properties are no longer copied into the ViewData dictionary. Instead, the Employee instance is passed directly to the view.

using System.Web.Mvc;
using MvcApplication1.Models;

namespace MvcApplication1.Controllers
{
public class EmployeeController : Controller
{
public ActionResult Show(string firstname)
{
Employee employee = null;

if (string.IsNullOrEmpty(firstname))
{
ViewData["ErrorMessage"] = "No firstname provided!";
}
else
{
employee = new Employee
{
FirstName = firstname,
LastName = "Example",
Email = firstname + "@example.com"
};
}

return View(employee);
}
}
}

Note that we are passing the model data to the View() method. Alternatively, this can be done by stating Model = employee prior to returning the view. If you run the application, the result should be exactly the same as before.

Creating a new view

During the development of the controller action method, creating a corresponding view is very straightforward. To create a new view for the current controller action, right-click somewhere on the method body, and select Add view... from the context menu. The following dialog box will be displayed:

Your First ASP.NET MVC Application

In the Add view dialog box, some options can be specified. First of all, the view name can be modified if required. By default, this name will be the same as the action method name. It's also possible to select a view template, which we will set to Empty. This template can be used to easily create a view—for example, one which shows the details of an employee.

From this dialog, it's also possible to make the view strongly-typed by simply selecting the corresponding checkbox and choosing the class to base the view on. The last option in this dialog box allows you to specify the master page.

Unit testing the controller

Unit testing is a software development process in which the smallest testable parts of an application, called units, are individually and independently tested for correct operation. Typically, these units are individual methods being tested. Most often, unit tests are run automatically, and provide immediate feedback (successful/unsuccessful/unknown result) to a developer on the changes he or she has just made to the code. If a test is unsuccessful, the changes to the code should be reviewed because the expected behavior of a portion of source code has changed and may affect other units or the application as a whole.

When we created the ASP.NET MVC web application, a test project was also created. This already contains an example test class for HomeController, testing both the Index and About actions.

In the MvcApplication1Tests project, right-click on the Controllers folder, and then select Add | Unit Test from the context menu. From the wizard that is displayed, select the Show method of EmployeeController and click on OK. Visual Studio will generate a test class.

Your First ASP.NET MVC Application

Modify the generated test class to look like the following code:

using System.Web.Mvc;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MvcApplication1.Controllers;

namespace MvcApplication1Tests.Controllers
{
/// <summary>
/// Summary description for EmployeeControllerTest
/// </summary>
[TestClass]
public class EmployeeControllerTest
{
[TestMethod]
public void show_action_creates_employee_and_passes_to
_view_when_firstname_is_specified()
{
// Setup
EmployeeController controller = new EmployeeController();

// Execute
ViewResult result = controller.Show("Maarten") as
ViewResult;

// Verify
Assert.IsNotNull(result);
ViewDataDictionary viewData = result.ViewData;
Assert.IsNotNull(viewData.Model);
Assert.AreEqual("Maarten", (viewData.Model as
MvcApplication1.Models.Employee).FirstName);
Assert.IsNull(viewData["ErrorMessage"]);
}

[TestMethod]
public void show_action_passes_error_model_to
_view_when_no_firstname_specified()
{
// Setup
EmployeeController controller = new EmployeeController();

// Execute
ViewResult result = controller.Show(null) as ViewResult;

// Verify
Assert.IsNotNull(result);
ViewDataDictionary viewData = result.ViewData;
Assert.IsNull(viewData.Model);
Assert.IsNotNull(viewData["ErrorMessage"]);
}
}
}

Each test method is first initializing a new EmployeeController, after which the action method that needs to be tested is called. When the action method returns an ActionResult, it is cast to ViewResult on which some assertions are made. For example, if the Show action method of EmployeeController is called with parameter Maarten, an assertion is made that the controller passes the correct employee data to the view.

This test suite does not require the application to be deployed on a web server. Instead, the EmployeeController is tested directly in the code. The test asserts that some properties of the ViewData are present. For example, if the Show() action is called with the parameter, Maarten, the Model should not be null and should contain an Employee with the first name, Maarten.

Summary

In this article, we have seen an overview of all aspects of an ASP.NET MVC web application. We started by exploring the ASP.NET MVC web application project template that is installed in Visual Studio 2008, after which we created our own action method and corresponding view.

Another thing that we have seen is how to create a strong-typed view and how a controller action method can pass strong-typed ViewData to the view.

We ended this article by looking at the various aspects of unit testing—what it is, why it is used, how to create a unit test for an action method by using Visual Studio's unit test generation wizard, and modifying the unit test code by hand.


Further resources on this subject:


About the Author :


Maarten Balliauw

Maarten Balliauw has a Bachelor's Degree in Software Engineering and has
about eight years of experience in software development. He started his career
during his studies where he founded a company that did web development in PHP
and ASP.NET. After graduation, he sold his shares and joined one of the largest
ICT companies in Belgium, RealDolmen, where he continued web application
development in ASP.NET and application life cycle management in Visual Studio
Team System. He is a Microsoft Certifi ed Technology Specialist in ASP.NET and
works with the latest Microsoft technologies such as LINQ and ASP.NET 3.5. He has
published many articles in both .NET and PHP literature, such as MSDN magazine
Belgium, and PHP Architect. Ever since the fi rst announcement of the ASP.NET MVC
framework, he has been following all its developments and features.

Books From Packt

Entity Framework Tutorial
Entity Framework Tutorial

ASP.NET Data Presentation Controls Essentials
ASP.NET Data Presentation Controls Essentials

Microsoft Dynamics AX 2009 Development Cookbook
Microsoft Dynamics AX 2009 Development Cookbook

Microsoft Office Live Small Business: Beginner’s Guide
Microsoft Office Live Small Business: Beginner’s Guide

Microsoft Dynamics AX 2009 Programming: Getting Started
Microsoft Dynamics AX 2009 Programming: Getting Started

Learning SQL Server 2008 Reporting Services
Learning SQL Server 2008 Reporting Services

Programming Microsoft Dynamics NAV 2009
Programming Microsoft Dynamics NAV 2009

CodeIgniter for Rapid PHP Application Development
CodeIgniter for Rapid PHP Application Development

 

 

 

 

Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software