This is a rough draft of a chapter from the book
ASP.NET MVC Framework Unleashed by Stephen Walther. Comments are welcome and appreciated. When the book is published, the text from this blog entry will be removed and only the code listings will remain.
Order this Book from Amazon
In the previous chapter, we discussed all of the lofty goals of the ASP.NET MVC framework. In this chapter, we completely ignore them. In this chapter, we build a simple database-driven ASP.NET MVC application in the easiest way possible. We ignore design principles and patterns. We don’t create a single unit test. The goal is to clarify the basic mechanics of building an ASP.NET MVC application.
Over the course of this chapter, we build a simple Toy Store application. Our Toy Store application will enable us to display a list of toys and create new toys. In other words, it will illustrate how to build a web application that performs basic database operations.
*** Begin Note ***
The third part of this book is devoted to an extended walkthrough of building an ASP.NET MVC application in the “right” way. We build a forums application by using test-driven development and software design principles and patterns.
*** End Note ***
Starting with a Blank Slate
Let’s start by creating a new ASP.NET MVC application and removing all of the sample files. Follow these steps to create a new ASP.NET MVC Web Application Project:
1. Launch Visual Studio 2008.
2. Select the menu option File, New Project.
3. In the New Project dialog, select your preferred programming language and select the ASP.NET MVC Web Application template (see Figure 1).
4. Name your new project ToyStore and click the OK button.
Figure 1 – Creating a new ASP.NET MVC application

When you create a new ASP.NET MVC project, the Create Unit Test Project dialog appears automatically (see Figure 2). When asked whether you want to create a unit test project, select the option Yes, create a unit test project (In general, you should always select this option because it is a pain to add a new unit test project to your solution after your ASP.NET MVC project is already created).
Figure 2 – The Create Unit Test Project dialog

*** Begin Note ***
The Create Unit Test Project dialog won’t appear when you create an ASP.NET MVC application in Microsoft Visual Web Developer. Visual Web Developer does not support Test projects.
*** End Note ***
As we discussed in the previous chapter, when you create a new ASP.NET MVC application you get several sample files by default. These files will get in our way as we build a new application. Delete the following files from your ASP.NET MVC project:
[C#]
\Controllers\HomeController.cs
\Views\Home\About.aspx
\Views\Home\Index.aspx
[VB]
\Controllers\HomeController.vb
\Views\Home\About.aspx
\Views\Home\Index.aspx
Delete the following file from your Test project.
[C#]
\Controllers\HomeControllerTest.cs
[VB]
\Controllers\HomeControllerTest.vb
*** Begin Tip ***
If you always want to start with an empty ASP.NET MVC project then you can create a new Visual Studio project template after deleting the sample files. Create a new project template by selecting the menu option File, Export Template.
*** End Tip ***
Creating the Database
We need to create a database and database table to contain our list of toys for our toy store. The ASP.NET MVC framework is compatible with any modern database including Oracle 11g, MySQL, and Microsoft SQL Server.
In this book, we’ll use Microsoft SQL Server Express for our database. Microsoft SQL Server Express is the free version of Microsoft SQL Server. It includes all of the basic functionality of the full version of Microsoft SQL Server (it uses the same database engine).
*** Begin Note ***
You can install Microsoft SQL Server Express when you install Visual Studio or Visual Web Developer (it is an installation option). You also can download Microsoft SQL Server Express by using the Web Platform Installer which you can download from the following website:
http://www.asp.net/downloads/
*** End Note ***
Follow these steps to create a new database from within Visual Studio:
1. Right-click the App_Data folder in the Solution Explorer window and select the menu option Add, New Item.
2. In the Add New Item dialog, select the SQL Server Database template (see Figure 3).
3. Give the new database the name ToyStoreDB.
4. Click the Add button.
Figure 3 – Adding a new SQL Server database

After you create the database, you need to create the database table that will contain the list of toys. Follow these steps to create the Products database table:
1. Double-click the ToyStoreDB.mdf file in the App_Data folder to open the Server Explorer window and connect to the ToyStoreDB database.
2. Right-click the Tables folder and select the menu option Add New Table.
3. Enter the columns listed in Table 1 into the Table Designer (see Figure 4).
4. Set the Id column as an Identity column by expanding the Identity Specification node under Column Properties and setting the (Is Identity) property to the value Yes.
5. Set the Id column as the primary key column by selecting this column in the Table Designer and clicking the Set Primary Key button (the button with an icon of a key).
6. Save the new table by clicking the Save button (the button with the anachronistic icon of a floppy disk).
7. In the Choose Name dialog, enter the table named Products.
Table 1 – Columns in the Products table
| Column Name |
Data Type |
Allow Nulls |
| Id |
int |
false |
| Name |
nvarchar(100) |
false |
| Description |
nvarchar(MAX) |
false |
| Price |
money |
false |
Figure 4 – Creating the Products table

*** Begin Note ***
The Server Explorer window is called the Database Explorer window in the case of Visual Web Developer.
*** End Note ***
After you finish creating the Products database table, you should add some database records to the table. Right-click the Products table in the Server Explorer window and select the menu option Show Table Data. Enter two or three products (see Figure 5).
Figure 5 – Entering sample data in the Products database table

Creating the Model
We need to create model classes to represent our database tables in our ASP.NET MVC application. The easiest way to create the data model classes is to use an Object Relational Mapping (ORM) tool to generate the classes from a database automatically.
You can use your favorite ORM with the ASP.NET MVC framework. The ASP.NET MVC framework is not tied to any particular ORM. For example, ASP.NET MVC is compatible with Microsoft LINQ to SQL, NHibernate, and the Microsoft Entity Framework.
In this book, we use the Microsoft Entity Framework to generate our data model classes. We focus on the Microsoft Entity Framework because the Microsoft Entity Framework is Microsoft’s recommended data access solution.
*** Begin Note ***
In order to use the Microsoft Entity Framework, you need to install .NET Framework 3.5 Service Pack 1.
*** End Note ***
Follow these steps to generate the data model classes:
1. Right-click the Models folder in the Solution Explorer window and select the menu option Add, New Item.
2. Select the Data category and the ADO.NET Entity Data Model template (see Figure 6).
3. Name the data model ToyStoreDataModel.edmx and click the Add button.
Figure 6 – Adding ADO.NET Entity Data Model classes

After you complete these steps, the Entity Model Data Wizard launches. Complete these wizard steps:
1. In the Choose Model Contents step, select the Generate from database option.
2. In the Choose Your Data Connection step, select the ToyStoreDB.mdf data connection and the entity connection name ToyStoreDBEntities (see Figure 7).
3. In the Choose Your Database Objects step, select the Products database table and enter Models for the namespace (see Figure 8).
4. Click the Finish button to complete the wizard.
Figure 7 – Choose your data connection

Figure 8 – Entering the model namespace

After you complete the Entity Data Model Wizard, the Entity Designer appears with a single entity named Products (see Figure 9). The Entity Framework has generated a class named Products that represents your Products database table.
Most likely, you’ll want to rename the classes generated by the Entity Framework. The Entity Framework simply names its entities with the same names as the database tables. Because the Products class represents a particular product, you’ll want to change the name of the class to Product (singular instead of plural).
Right-click the Products entity in the Entity Designer and select the menu option Rename. Provide the new name Product.
Figure 9 – The Entity Designer

At this point, we have successfully created our data model classes. We can use these classes to represent our ToyStoreDB database within our ASP.NET MVC application.
*** Begin Note ***
You can open the Entity Designer at any time in the future by double-clicking the ToyStoreDataModel.edmx file in the Models folder.
*** End Note ***
Creating the Controller
The controllers in an ASP.NET MVC application control the flow of application execution. The controller that is invoked by default is named the Home controller. We need to create the Home controller by following these steps:
1. Right-click the Controllers folder and select the menu option Add Controller.
2. In the Add Controller dialog, enter the controller name HomeController and select the option labeled Add action methods for Create, Update, and Details scenarios (see Figure 10).
3. Click the Add button to create the new controller.
Figure 10 – Adding a new controller

The Home controller is contained in Listing 1.
Listing 1 – Controllers\HomeController.cs [C#]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
namespace ToyStore.Controllers
{
public class HomeController : Controller
{
//
// GET: /Home/
public ActionResult Index()
{
return View();
}
//
// GET: /Home/Details/5
public ActionResult Details(int id)
{
return View();
}
//
// GET: /Home/Create
public ActionResult Create()
{
return View();
}
//
// POST: /Home/Create
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(FormCollection collection)
{
try
{
// TODO: Add insert logic here
return RedirectToAction("Index");
}
catch
{
return View();
}
}
//
// GET: /Home/Edit/5
public ActionResult Edit(int id)
{
return View();
}
//
// POST: /Home/Edit/5
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(int id, FormCollection collection)
{
try
{
// TODO: Add update logic here
return RedirectToAction("Index");
}
catch
{
return View();
}
}
}
}
Listing 1 – Controllers\HomeController.vb [VB]
Public Class HomeController
Inherits System.Web.Mvc.Controller
'
' GET: /Home/
Function Index() As ActionResult
Return View()
End Function
'
' GET: /Home/Details/5
Function Details(ByVal id As Integer) As ActionResult
Return View()
End Function
'
' GET: /Home/Create
Function Create() As ActionResult
Return View()
End Function
'
' POST: /Home/Create
<AcceptVerbs(HttpVerbs.Post)> _
Function Create(ByVal collection As FormCollection) As ActionResult
Try
' TODO: Add insert logic here
Return RedirectToAction("Index")
Catch
Return View()
End Try
End Function
'
' GET: /Home/Edit/5
Function Edit(ByVal id As Integer) As ActionResult
Return View()
End Function
'
' POST: /Home/Edit/5
<AcceptVerbs(HttpVerbs.Post)> _
Function Edit(ByVal id As Integer, ByVal collection As FormCollection) As ActionResult
Try
' TODO: Add update logic here
Return RedirectToAction("Index")
Catch
Return View()
End Try
End Function
End Class
Because we selected the option to generate Create, Update, and Details methods when creating the Home controller, the Home controller in Listing 1 includes these actions. In particular, the Home controller exposes the following actions:
· Index() – This is the default action of the controller. Typically, this action is used to display a list of items.
· Details(id) – This action displays details for a particular item.
· Create() -- This action displays a form for creating a new item.
· Create(collection) – This action inserts the new item into the database.
· Edit(id) – This action displays a form for editing an existing item.
· Edit(id, collection) -- This action update the existing item in the database.
Currently, the Home controller only contains stubs for these actions. Let’s go ahead and take advantage of the data model classes that we created with the Entity Framework to implement the Index() and Create() actions. The updated Home controller is contained in Listing 2.
Listing 2 – Controllers\HomeController.cs [C#]
using System.Linq;
using System.Web.Mvc;
using ToyStore.Models;
namespace ToyStore.Controllers
{
public class HomeController : Controller
{
private ToyStoreDBEntities _dataModel = new ToyStoreDBEntities();
//
// GET: /Home/
public ActionResult Index()
{
return View(_dataModel.ProductSet.ToList());
}
//
// GET: /Home/Create
public ActionResult Create()
{
return View();
}
//
// POST: /Home/Create
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create([Bind(Exclude="Id")]Product productToCreate)
{
if (!ModelState.IsValid)
return View();
try
{
_dataModel.AddToProductSet(productToCreate);
_dataModel.SaveChanges();
return RedirectToAction("Index");
}
catch
{
return View();
}
}
}
}
Listing 2 – Controllers\HomeController.vb [VB]
Public Class HomeController
Inherits System.Web.Mvc.Controller
Private _dataModel As New ToyStoreDBEntities()
'
' GET: /Home/
Function Index() As ActionResult
Return View(_dataModel.ProductSet.ToList())
End Function
'
' GET: /Home/Create
Function Create() As ActionResult
Return View()
End Function
'
' POST: /Home/Create
<AcceptVerbs(HttpVerbs.Post)> _
Function Create(<Bind(Exclude:="Id")> ByVal productToCreate As Product) As ActionResult
If Not ModelState.IsValid Then
Return View()
End If
Try
_dataModel.AddToProductSet(productToCreate)
_dataModel.SaveChanges()
Return RedirectToAction("Index")
Catch
Return View()
End Try
End Function
End Class
Notice that a private field named _dataModel of type DBStoreEntities is defined at the top of the controller in Listing 2. The DBStoreEntities class was one of the classes that were generated by the Entity Model Data Wizard. We use this class to communicate with the database.
The Index() action has been modified to return a list of products. The expression _dataModel.ProductSet.ToList() returns a list of products from the Products database table.
There are two Create() actions. The first Create() action displays the form for creating a new product. The form is submitted to the second Create() action which actually performs the database insert of the new product.
Notice that the second Create() action has been modified to accept a Product parameter. The Product class also was generated by the Entity Model Data Wizard. The Product class has properties that correspond to each column in the underlying Products database table.
Finally, the Create() action calls the following methods to add the new product to the database:
[C#]
_dataModel.AddToProductSet(productToCreate);
_dataModel.SaveChanges();
[VB]
_dataModel.AddToProductSet(productToCreate)
_dataModel.SaveChanges()
Our Home controller now contains all of the necessary database logic. We can use the controller to return a set of products and we can use the controller to create a new product.
Notice that both the Index() action and the first Create() action return a View. The next and final step is to create these views.
Creating the Views
An MVC view contains all of the HTML markup and view logic required to generate an HTML page. The set of views exposed by an ASP.NET MVC application is the public face of the application.
*** Begin Note ***
A view does not need to be HTML. For example, you can create Silverlight views.
*** End Note ***
Our simple application needs two views: the Index and the Create view. We’ll use the Index view to display the list of products and the Create view to display a form for creating new products.
Adding the Index View
Let’s start by creating the Index view. Follow these steps:
1. Build your application by selecting the menu option Build, Build Solution.
2. Right-click the Index() action in the Code editor window and select the menu option Add View (see Figure 11).
3. In the Add View dialog, select the option Create a strongly-typed view.
4. In the Add View dialog, from the dropdown list labeled View data class, select the ToyStore.Models.Product class.
5. In the Add View dialog, from the dropdown list labeled View Content, select List.
6. Click the Add button to add the new view to your project (see Figure 12).
Figure 11 – Adding a view

Figure 12 – The Add View dialog

*** Begin Note ***
You need to build your ASP.NET MVC application before adding a view with the Add View dialog in order to build the classes displayed by the View data class dropdown list. If your application has build errors then this list will be blank.
*** End Note ***
Views are added to the Views folder. Views follow a particular naming convention. A view returned by the Index() action exposed by the Home controller class is located at the following path:
\Views\Home\Index.aspx
In general, views follow the naming convention:
\Views\Controller Name\Action Name.aspx
The contents of the Index view are contained in Listing 3. This view loops through all of the products and displays the products in an HTML table (see Figure 13).
Listing 3 – Views\Home\Index.aspx [C#]
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<ToyStore.Models.Product>>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
<title>Index</title>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Index</h2>
<table>
<tr>
<th></th>
<th>
Id
</th>
<th>
Name
</th>
<th>
Description
</th>
<th>
Price
</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.Name) %>
</td>
<td>
<%= Html.Encode(item.Description) %>
</td>
<td>
<%= Html.Encode(item.Price) %>
</td>
</tr>
<% } %>
</table>
<p>
<%= Html.ActionLink("Create New", "Create") %>
</p>
</asp:Content>
Listing 3 – Views\Home\Index.aspx [VB]
<%@ Page Title="" Language="VB" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage(Of IEnumerable(Of ToyStore.Product))" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
<title>Index</title>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Index</h2>
<p>
<%=Html.ActionLink("Create New", "Create")%>
</p>
<table>
<tr>
<th></th>
<th>
Id
</th>
<th>
Name
</th>
<th>
Description
</th>
<th>
Price
</th>
</tr>
<% For Each item In Model%>
<tr>
<td>
<%--<%=Html.ActionLink("Edit", "Edit", New With {.id = item.PrimaryKey})%> |
<%=Html.ActionLink("Details", "Details", New With {.id = item.PrimaryKey})%>--%>
</td>
<td>
<%=Html.Encode(item.Id)%>
</td>
<td>
<%=Html.Encode(item.Name)%>
</td>
<td>
<%=Html.Encode(item.Description)%>
</td>
<td>
<%=Html.Encode(item.Price)%>
</td>
</tr>
<% Next%>
</table>
</asp:Content>
Figure 13 – The Index view

Notice that the Index view includes a link labeled Create New that appears at the bottom of the view. We add the Create view in the next section.
Adding the Create View
The Create view displays the HTML form for adding a new product. We can follow a similar set of steps to add the Create view:
1. Right-click the first Create() action in the Code editor window and select the menu option Add View.
2. In the Add View dialog, select the option Create a strongly-typed view.
3. In the Add View dialog, from the dropdown list labeled View data class, select the ToyStore.Models.Product class.
4. In the Add View dialog, from the dropdown list labeled View Content, select Create.
5. Click the Add button to add the new view to your project (see Figure 14).
Figure 14 – Adding the Create view

The Create view is added to your project at the following location:
\Views\Home\Create.aspx
The contents of the Create view are contained in Listing 4.
Listing 4 – Views\Home\Create.aspx [C#]
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<ToyStore.Models.Product>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
<title>Create</title>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Create</h2>
<%= Html.ValidationSummary() %>
<% using (Html.BeginForm()) {%>
<fieldset>
<legend>Fields</legend>
<p>
<label for="Id">Id:</label>
<%= Html.TextBox("Id") %>
<%= Html.ValidationMessage("Id", "*") %>
</p>
<p>
<label for="Name">Name:</label>
<%= Html.TextBox("Name") %>
<%= Html.ValidationMessage("Name", "*") %>
</p>
<p>
<label for="Description">Description:</label>
<%= Html.TextBox("Description") %>
<%= Html.ValidationMessage("Description", "*") %>
</p>
<p>
<label for="Price">Price:</label>
<%= Html.TextBox("Price") %>
<%= Html.ValidationMessage("Price", "*") %>
</p>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
<% } %>
<div>
<%=Html.ActionLink("Back to List", "Index") %>
</div>
</asp:Content>
Listing 4 – Views\Home\Create.aspx [VB]
<%@ Page Title="" Language="VB" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage(Of ToyStore.Product)" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
<title>Create</title>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Create</h2>
<%= Html.ValidationSummary() %>
<% Using Html.BeginForm()%>
<fieldset>
<legend>Fields</legend>
<p>
<label for="Id">Id:</label>
<%= Html.TextBox("Id") %>
<%= Html.ValidationMessage("Id", "*") %>
</p>
<p>
<label for="Name">Name:</label>
<%= Html.TextBox("Name") %>
<%= Html.ValidationMessage("Name", "*") %>
</p>
<p>
<label for="Description">Description:</label>
<%= Html.TextBox("Description") %>
<%= Html.ValidationMessage("Description", "*") %>
</p>
<p>
<label for="Price">Price:</label>
<%= Html.TextBox("Price") %>
<%= Html.ValidationMessage("Price", "*") %>
</p>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
<% End Using %>
<div>
<%=Html.ActionLink("Back to List", "Index") %>
</div>
</asp:Content>
The Create view displays an HTML form for creating new products (see Figure 15). The Add View dialog generates HTML form fields that correspond to each of the properties of the Product class. If you complete the HTML form and submit it, a new product will be created in the database.
Figure 15 – The Create view

Summary
In this chapter, we used the ASP.NET MVC framework to build a simple database-driven web application. We created models, views, and controllers.
First, we created a database and a database model. We used Microsoft SQL Server Express for our database. We created our database model classes by taking advantage of the Microsoft Entity Framework.
Next, we created the Home controller. We used Visual Studio to generate the actions for our Home controller automatically. We added a few lines of data access logic to interact with our database.
Finally, we created two views. We created an Index view that displays a list of all of the products in an HTML table. We also added a Create view that displays an HTML form for adding a new product to the database.
Download the Code