MVC:: Creating A Tasklist Application With
MVC:: Creating A Tasklist Application With
ASP.NET MVC
The purpose of this tutorial is to give you a sense of “what it is like” to build an ASP.NET
MVC application. In this tutorial, I blast through building an entire ASP.NET MVC application
from start to finish. I show you how to build a simple Tasklist application.
If you have worked with Active Server Pages or ASP.NET, then you should find ASP.NET
MVC very familiar. ASP.NET MVC views are very much like the pages in an Active Server
Pages application. And, just like a traditional ASP.NET Web Forms application, ASP.NET MVC
provides you with full access to the rich set of languages and classes provided by the .NET
framework.
My hope is that this tutorial will give you a sense of how the experience of building an
ASP.NET MVC application is both similar and different than the experience of building an
Active Server Pages or ASP.NET Web Forms application.
Preliminaries
You’ll need either Visual Studio 2008 or Visual Web Developer 2008 Express to build an
ASP.NET MVC application. You also need to download the ASP.NET MVC framework.
If you don’t own Visual Studio 2008, then you can download a 90 day trial version of Visual
Studio 2008 from this website:
http://msdn.microsoft.com/en-us/vs2008/products/cc268305.aspx
Alternatively, you can create ASP.NET MVC applications with Visual Web Developer Express
2008. If you decide to use Visual Web Developer Express then you must have Service Pack
1 installed. You can download Visual Web Developer 2008 Express with Service Pack 1 from
this website:
http://www.microsoft.com/downloads/details.aspx?FamilyId=BDB6391C-05CA-4036-9154-
6DF4F6DEBD14&displaylang=en
After you install either Visual Studio 2008 or Visual Web Developer 2008, you need to install
the ASP.NET MVC framework. You can download the ASP.NET MVC framework from the
following website:
http://www.asp.net/mvc/
Whenever you create a new MVC Web Application project, Visual Studio prompts you to
create a separate unit test project. The dialog in Figure 2 appears. Because we won’t be
creating tests in this tutorial because of time constraints (and, yes, we should feel a little
guilty about this) select the No option and click the OK button.
Figure 2 – The Create Unit Test Project dialog
An ASP.NET MVC application has a standard set of folders: a Models, Views, and Controllers
folder. You can see this standard set of folders in the Solution Explorer window. We’ll need
to add files to the Models, Views, and Controllers folders to build our TaskList application.
When you create a new MVC application by using Visual Studio, you get a sample
application. Because we want to start from scratch, we need to delete the content for this
sample application. You need to delete the following file and the following folder:
Controllers\HomeController.cs
Views\Home
For our TaskList application, we’ll modify the HomeController class so that it contains the
code in Listing 1. The modified controller contains four functions named Index(), Create(),
CreateNew(), and Complete(). Each function corresponds to a controller action.
Listing 1 – HomeController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using TaskList.Models;
namespace TaskList.Controllers
{
public class HomeController : Controller
{
// Display a list of tasks
public ActionResult Index()
{
return View();
}
Create() – Called when you want to display the form for adding a new task.
CreateNew() – Called when the form for adding a new task is submitted. This
controller action actually adds the new task to the database.
Complete() – Called when a new task is marked as completed.
We’ll need to add additional logic to our controller actions to get them to work as intended.
Any public function contained in a controller class is exposed as a controller action. Be
careful about this. A controller action is exposed to the world. Anyone can call a controller
action by typing the right URL into the address bar of their web browser. So, don’t
accidently create a public function in a controller when you don’t want the function to be
called.
Notice that controller actions return an ActionResult. An ActionResult represents what the
action will do. The first two controller actions, Index() and Create(), return an MVC view.
The third and fourth action results redirect the user to another controller action.
Here’s how these controller actions work. When you request the Create() controller action,
a view containing a form for creating a new task is returned. When you submit this form,
the CreateNew() controller action is called. The CreateNew() controller action adds the new
task to the database and redirects the user to the Index() controller action. The Index()
controller action returns a view that displays the entire list of tasks. Finally, if you mark a
task as completed, the Complete() controller action is called and the database is updated.
The Complete() action redirects the user back to the Index() action and the updated list of
tasks is displayed.
A view can contain HTML content and scripts. The Index.aspx view will be used to display
the list of all tasks. To indicate the purpose of the view, add the content in Listing 2 to the
Index.aspx view.
Listing 2 – Index.aspx
<%@ Page Language="C#" AutoEventWireup="false"
CodeBehind="Index.aspx.cs" Inherits="TaskList.Views.Home.Index"
%>
<h1>My Tasks</h1>
</div>
</body>
</html>
The Index.aspx view currently does not display any tasks – it just claims that it will. We
will add the script to display the list of tasks to the Index.aspx page later in this tutorial.
Notice that the Index.aspx view includes a link labeled Add new Task. This link points to
the path /Home/Create. When you click this link, the Create() action of the
HomeController class is invoked. The Create() method returns the Create view.
The Create.aspx view contains a form for creating a new task. The contents of this view
are contained in Listing 3.
Listing 3 – Create.aspx
<%@ Page Language="C#" AutoEventWireup="false"
CodeBehind="Create.aspx.cs" Inherits="TaskList.Views.Home.Create"
%>
<label for="description">Task:</label>
<br />
<input type="submit" value="Add Task" />
</form>
</div>
</body>
</html>
Notice that the form contained in Listing 3 posts to the following URL:
/Home/CreateNew.aspx
This URL corresponds to the CreateNew() action on the HomeController controller. The
form data representing the new task will be posted to this action.
The first column, the Id column, has two special properties. First, you need to mark the Id
column as the primary key column. After selecting the Id column, click the Set Primary
Key button (it is the icon that looks like a key). Second, you need to mark the Id column as
an Identity column. In the Column Properties window, scroll down to the Identity
Specification section and expand it. Change the Is Identity property to the value Yes.
When you are finished, the table should look like Figure 4.
Figure 4 – The Tasks table
The final step is to save the new table. Click the Save button (the icon of the floppy) and
give the new table the name Tasks.
namespace TaskList.Controllers
{
public class HomeController : Controller
{
db.Tasks.InsertOnSubmit(newTask);
db.SubmitChanges();
return RedirectToAction("Index");
}
db.SubmitChanges();
return RedirectToAction("Index");
}
}
}
Notice that the HomeController class in Listing 4 contains a class-level private field named
db. The db field is an instance of the TaskListDataContext class. The HomeController
class uses the db field to represent the TaskListDB database.
The Index() controller action has been modified to retrieve all of the records from the
Tasks database table. The tasks are passed to the Index view.
The CreateNew() method has been modified to create a new task in the Tasks database
table. Notice that the CreateNew() method has been modified to accept a String parameter
named description. This parameter represents the description text form field passed from
the Create view. The ASP.NET MVC framework passes form fields as parameters to a
controller action automatically.
Finally, the Complete() method has been modified to change the value of the IsComplete
column in the Tasks database table. When you mark a task as complete, the Id of the task
is passed to the Complete() action and the database is updated.
<h1>My Tasks</h1>
<ul>
<% foreach (Task task in (IEnumerable)ViewData.Model) { %>
<li>
<% if (task.IsCompleted) {%>
<del>
<%= task.EntryDate.ToShortDateString() %>
-- <%=task.Description%>
</del>
<% } else {%>
<a href="/Home/Complete/<%= task.Id.ToString()
%>">Complete</a>
<%= task.EntryDate.ToShortDateString() %>
-- <%=task.Description%>
<% }%>
</li>
<% } %>
</ul>
</div>
</body>
</html>
The Index view in Listing 5 contains a C# foreach loop that iterates through all of the tasks.
The tasks are represented with the ViewData.Model property. In general, you use ViewData
to pass data from a controller action to a view.
Within the loop, a conditional is used to check whether a task has been completed. A
completed task is shown with a line through it (struck out). The HTML <del> tag is used to
create the line through the completed tasks. If a task has not been completed, a link labeled
Complete is displayed next to the task. The link is constructed with the following script:
<a href="/Home/Complete/<%= task.Id.ToString() %>">Complete</a>
Notice that the Id of the task is included in the URL represented by the link. The task Id is
passed to the Complete() action of the HomeController class when you click a link. In this
way, the right database record is updated when you click the Complete link.
The final version of the Index view displays the page contained in Figure 6.
Figure 6 – The Index View
Summary
The purpose of this tutorial was to give you a sense of the experience of building an
ASP.NET MVC application. I hope that you discovered that building an ASP.NET MVC web
application is very similar to the experience of building an Active Server Pages or ASP.NET
application.
In this tutorial, we examined only the most basic features of the ASP.NET MVC framework.
In future tutorials, we dive deeper into topics such as controllers, controller actions, views,
view data, and HTML helpers.