Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

A Simple Tutorial on Developing ASP.NET Applications in MVC Pattern

0.00/5 (No votes)
13 May 2010 2  
This article gives a simple tutorial on developing ASP.NET applications in MVC pattern.

Introduction

This article gives a simple tutorial on developing ASP.NET applications in MVC pattern.

Background

One of the recent developments in ASP.NET is the MVC (Model–View–Controller) design pattern. MVC pattern isolates the application logic for the users from input and presentation (GUI).

According to Scott Guthrie, MVC pattern has the following advantages:

  • One of the benefits of using a MVC methodology is that it helps enforce a clean separation of concerns between the models, views and controllers within an application. Maintaining a clean separation of concerns makes the testing of applications much easier, since the contract between different application components are more clearly defined and articulated.
  • The MVC pattern can also help enable red/green test driven development (TDD) - where you implement automated unit tests, which define and verify the requirements of new code, first before you actually write the code itself.

The following picture borrowed from Wikipedia shows the MVC pattern:

MVCDiagram.jpg

MVC divides an application into three concerns:

  • Model - Encapsulates core application data and functionality Domain Logic.
  • View - obtains data from the model and presents it to the user.
  • Controller - receives and translates input to requests on the model or the view.

Scott Guthrie gave a very good and detailed introduction on applying MVC pattern to ASP.NET projects in his blog. For obvious reasons, his introduction is very comprehensive and authoritative. It should be the first reference for application developers who want to understand ASP.NET MVC.

This article is intended to give a simpler tutorial on developing ASP.NET MVC applications in the Microsoft Visual Studio context to help application developers to get a quick start.

When working on ASP.NET MVC web sites, the first thing you may notice is that the URLs to access the web pages are no longer the familiar "http://www.codeproject.com/info/search.aspx" style. Instead the URLs will look like http://localhost/VirtualDirectoryName/Controller/Action.

After reading this article, hopefully you will be able to quickly develop your own ASP.NET MVC web applications in Visual Studio. The article is intended to answer the following questions:

  • How are the ASP.NET MVC URLs associated to the resources on the web server?
  • In ASP.NET, what are the Models, Views, and Controllers and how are they implemented?
  • How is information passed among the Models, Views, and Controllers?
  • How does the application code on the server access the data passed to the server by URL parameters and form submissions from the browser?
  • How to access the session data in ASP.NET MVC?
  • How to use code behind when implementing the Views?

This tutorial application is developed in Visual Studio 2008, and the language used is C#. If you have Visual Studio 2010, your environment may be different.

This article comes with the source code for this tutorial. It may be a good idea if you download the source code and run it in your Visual Studio before you start to read this tutorial. This should give you a better idea on the functions implemented in this simple tutorial ASP.NET MVC application. This should make your reading of this article easier. If you are unable to load the source code in your Visual Studio, you may need to first set up your development environment.

Let us begin the tutorial by first setting up our development environment.

Set up the Development Environment

In order to develop MVC ASP.NET applications, you will need to install the Visual Studio ASP.NET MVC Add-on. If you have not done so, you can go to the Microsoft web site to download the Add-on and install it on your computer.

Create an Empty MVC ASP.NET Project in Visual Studio

After installing the ASP.NET MVC Add-on, we can start to create an ASP.NET MVC project in Visual Studio.

CreateEmptyProject.jpg

We can create two types of ASP.NET MVC applications. In this tutorial, we will create an "ASP.NET MVC 2 Empty Web Application". Give the project the name "ASPNetMVCTutorial" and browse a folder where you want to save the files that the Visual Studio will be generating and click the "OK" button.

After the project is created, the solution explorer will have the following contents:

SolutionExplorerBeforeCleaning.jpg

In order to better focus on the MVC pattern in this ASP.NET development, I will be limiting the use of JavaScripts, and CSS style sheets. Let us delete the folders that are not MVC related and add a folder called "Utilities". The "Utilities" folder will be later used to add some utility classes to the project. After the cleaning, the solution explorer will have the following contents:

SolutionExplorerAfterCleaningUtil.jpg

In this project, we can see three folders generated by the "ASP.NET MVC 2 Empty Web Application" template:

  • Models
  • Views
  • Controllers

The models, views, and controllers (MVC) will be added into the corresponding folders later in this tutorial.

You can also notice that there are two "Web.config" files in the project. Most of the configuration information will be in the "Web.config" file in the root folder, the one in the "Views" folder is used to block direct access to the view "aspx" pages. For most of the ASP.NET MVC applications, we do not need to make changes to this "Web.config" file.

Add Some Configurations into the Root "Web.config" File

Before working on creating the models, views, and controllers, let us first change the "<AppSettings />" section of the "Web.config" file in the root folder to the following:

<appSettings>
    <add key="ApplicationName"
            value="A Simple Tutorial on How to Develop ASP.NET
		 Web Projects in MVC Pattern"/>
    <add key="Author" value="Song Li"/>
    <add key="DevelopmentTime" value="5/4/2010"/>
    <add key="DeploymentVirtualDirectory" value=""/>
</appSettings>

The configuration information will be used in the ASP.NET MVC application later.

Add Model Classes to the "Models" Folder

The models in the MVC pattern represent the application data. In this tutorial, we will be developing an application to manage a list of students. The application will allow the users to display, add, and delete the students. Right click the "Models" folder and choose to add a class. Give the class file a name called "StudentsModel.cs".

After the class is added, we can implement the class as the following:

using System;
using System.Data;
 
namespace ASPNetMVCTutorial.Models
{
    public class StudentsModel
    {
        private DataTable Students;
 
        public StudentsModel()
        {
            Students = new DataTable();
            DataColumn IDColumn = Students.Columns.Add
				("ID", Type.GetType("System.Int32"));
            IDColumn.AutoIncrement = true;
            IDColumn.AutoIncrementSeed = 1;
            IDColumn.AutoIncrementStep = 1;
 
            Students.Columns.Add("Name", Type.GetType("System.String"));
            Students.Columns.Add("Score", Type.GetType("System.Int32"));
            Students.Columns.Add("Time Added", Type.GetType("System.DateTime"));
 
            DataColumn[] keys = new DataColumn[1];
            keys[0] = IDColumn;
            Students.PrimaryKey = keys;
 
            Random rd = new Random();
            for (int Idex = 1; Idex <= 5; Idex++)
            {
                DataRow row = Students.NewRow();
                Students.Rows.Add(row);
                row["Name"] = "Student Name No. " + Idex.ToString();
                row["Score"] = 60 + rd.NextDouble() * 40;
                row["Time Added"] = System.DateTime.Now;
            }
        }
 
        public void AddStudent(string Name, int Score)
        {
            DataRow row = Students.NewRow();
            Students.Rows.Add(row);
            row["Name"] = Name;
            row["Score"] = Score;
            row["Time Added"] = System.DateTime.Now;
        }
 
        public void DeleteStudent(int ID)
        {
            DataRow RowToDelete = Students.Rows.Find(ID);
            if (RowToDelete != null)
            {
                Students.Rows.Remove(RowToDelete);
            }
        }
 
        public DataTable GetStudents()
        {
            return Students;
        }
    }
}

This class has a private variable "Students". Its data type is "DataTable". The information for the students is saved in this "DataTable". Besides the constructor, it exposes the methods to add and delete a student. The "GetSudents" method returns the "DataTable" which has the information for all the students to the caller. When an object of this class is first created, the constructor will initiate the "DataTable" and insert 5 randomly generated students in it.

For this ASP.NET MVC application to use the configuration information that we have added to the "Web.config" file, we will add another model class file called "ApplicationInformation.cs":

using System;
using System.Configuration;
 
namespace ASPNetMVCTutorial.Models
{
    public class ApplicationInformation
    {
        private static ApplicationInformation _thisInstance = null;
        private static object _threadLock = new Object();
 
        public string ApplicationName { get; private set; }
        public string Author { get; private set; }
        public string DevelopmentTime { get; private set; }
        public string DeploymentVirtualDirectory { get; private set; }
 
        public ApplicationInformation()
        {
            ApplicationName = ConfigurationManager.AppSettings["ApplicationName"];
            Author = ConfigurationManager.AppSettings["Author"];
            DevelopmentTime = ConfigurationManager.AppSettings["DevelopmentTime"];
            DeploymentVirtualDirectory = 
		ConfigurationManager.AppSettings["DeploymentVirtualDirectory"];
        }
 
        public static ApplicationInformation GetInstance()
        {
            lock (_threadLock)
            {
                if (_thisInstance == null)
                {
                    _thisInstance = new ApplicationInformation();
                }
            }
 
            return _thisInstance;
        }
    }
}

The ASP.NET MVC project will use the class "ApplicationInformation" to access the configurations.

Add a Utility Class to the "Utilities" Folder

To make the later development work easier, we will add a class "ApplicationUtility" to the "Utilities" folder. Right click the "Utilities" folder, and choose to add a class. Give the class file the name "ApplicationUtility.cs" and implement the class as the following:

using System;
using System.Text;
using ASPNetMVCTutorial.Models;
 
namespace ASPNetMVCTutorial.Utilities
{
    public static class ApplicationUtility
    {
        public static string FormatURL(string PathWithoutVirtualDirectoryName)
        {
            ApplicationInformation appInfomation 
                = ApplicationInformation.GetInstance();
            string DeploymentVirtualDirectory 
                = appInfomation.DeploymentVirtualDirectory;
 
            if (DeploymentVirtualDirectory == "")
            {
                return PathWithoutVirtualDirectoryName;
            }
 
            StringBuilder SB = new StringBuilder();
            SB.Append("/");
            SB.Append(appInfomation.DeploymentVirtualDirectory);
            SB.Append("/");
            SB.Append(PathWithoutVirtualDirectoryName);
 
            return SB.ToString();
        }
    }
}

The static method "FormatURL" is used to convert a relative ASP.NET MVC URL to an absolute URL depending on the virtual directory name at the deployment time. The virtual directory name is configured in the "Web.config" file. At development time, we will need to configure it as an empty string. At deployment time, we will have to put the correct virtual directory name in the "Web.config" file.

Add a Master Page for the ASP.NET MVC Project

Before adding the views, we will first add a master page for this ASP.NET project. By default, an ASP.NET MVC application will use master pages in Visual Studio, so let us first create a master page. The master page will be added to the "Views\Shared" folder.

Right click the "Views\Shared" folder and choose to add a new item.

AddMasterPage.jpg

Select the "Master Page" template, give the mater page the name "Site.Master" and click the "Add" button, the master page is added to the project.

We will implement the "Site.Master" file as the following:

<%@ Master Language="C#" 
    CodeBehind="~/Views/Shared/Site.Master.cs"
    Inherits="ASPNetMVCTutorial.Views.Shared.Site" %>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title><asp:Literal id="litAppTitle" runat="server" /></title>
    <style type="text/css">
        .ApplicationDefault {font-family: Verdana; font-size: 10px;}
        .Title {text-align: center; font-size: 12px; color:Maroon; font-family: 
                        Verdana; font-weight: bold;}
        .AuthorInformation {text-align: center; color:green; margin-top: 5px}
        .MainContent {margin-top: 10px; background-color: #F1FFFF; height: 600px; 
                              overflow: auto; width: 95%; text-align: center;
                              margin-left:auto; margin-right:auto;}
        .Copyright {margin-top: 10px; color: Gray; font-weight:bold; width: 100%; 
                            float: left; text-align: center;}
        .ErrorText {font-family: Verdana; font-weight: bold; color:Maroon;}
        .BoldText {font-family: Verdana; font-weight: bold;}
    </style>
</head>
 
<body class="ApplicationDefault">
    <div class="Title">
        <asp:Literal id="litApplicationName" runat="server" />
    </div>
    <div class="AuthorInformation">
        <asp:Literal id="litAuthorInformation" runat="server" />
    </div>
    
    <div id="MainContent" class="MainContent">
        <asp:ContentPlaceHolder id="ApplicationContent" runat="server" />
    </div>
    <div class="Copyright">Copy right: The Code Project Open License (CPOL)</div>
</body>
</html>

We will implement the code-behind file "Site.Master.cs" as the following:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text;
using System.Web.UI.WebControls;
using ASPNetMVCTutorial.Models;
using ASPNetMVCTutorial.Utilities;
 
namespace ASPNetMVCTutorial.Views.Shared
{
    public partial class Site : System.Web.Mvc.ViewMasterPage
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            ApplicationInformation appInfomation = ApplicationInformation.GetInstance();
            litAppTitle.Text = appInfomation.ApplicationName;
            litApplicationName.Text = appInfomation.ApplicationName;
 
            StringBuilder SB = new StringBuilder();
            SB.Append("Developed by ");
            SB.Append(appInfomation.Author);
            SB.Append(" on ");
            SB.Append(appInfomation.DevelopmentTime);
            litAuthorInformation.Text = SB.ToString();
        }
    }
}

The master page will be used for the entire project to control the display style and to display some general information about the application.

Add the Views to the "Views" Folder

The views in ASP.NET MVC are actually specialized "aspx" pages. In this project, we will be adding three views:

  • StudentList.aspx
  • AddStudent.aspx
  • Error.aspx

The "StudentList.aspx" is used to list all the students and to provide the user interactions to navigate to the "AddStudent.aspx" view to add student. It also provides the user interaction to delete the students. The "Error.aspx" view is used to display any possible errors during the operation.

The "StudentList.aspx" and "AddStudent.aspx" views will be added to the "Views\Students" folder and the "Error.aspx" will be added to the "Views\Shared" folder. Right click the folder "Views" and add a folder "Students" to it. We can then add the "StudentList.aspx" view. Right click the "Views\Students" folder and add a view.

AddView.jpg

Give the view the name "StudentList", choose the master page "Site.Master", type in the ContentPlaceHolderID as "ApplicationContent" and click the "Add" button. In the solution explorer, the view is created as "StudentList.aspx" file in the "Views\Students" folder.

AddViewWithoutCodeBehind.jpg

You may be surprised that the "StudentList.aspx" view does not have the familiar code-behind file. It is a hot discussion if the code-behind files should be used on the ASP.NET MVC views. Some people call the using of code-behind on views "Evil", but some other people say that it is "Not Evil". I am not going to get into this discussion. I just feel that if the application developers choose to use code-behind files, they should have the option to use it. We will add the code-behind file for the "StudentList.aspx" manually.

Right click the "Views\Students" folder and add a class file named "StudentList.aspx.cs". The "StudentList.aspx.cs" file will automatically implement a class "StudentList". Make the "SudentList" class inherit from "System.Web.Mvc.ViewPage". In the "StudentList.aspx" file, add the "CodeBehind" reference to the "StudentList.aspx.cs" and change the "Inherits" value to the class "StudentList". By doing this, the code behind file is manually added in the solution explorer:

AddViewWithCodeBehind.jpg

After adding the code behind file, we will implement the "StudentList.aspx" as the following:

<%@ Page Language="C#"
    MasterPageFile="~/Views/Shared/Site.Master"
    CodeBehind="~/Views/Students/StudentList.aspx.cs"
    Inherits="ASPNetMVCTutorial.Views.Students.StudentList" %>
 
<asp:Content id="IndexContent" ContentPlaceHolderID="ApplicationContent" runat="server">
    <div style="float: right; margin-right: 10px">
        <asp:HyperLink id="linkAddStudent" runat="server" 
		Text="Click to add a student to the list" />
    </div>
    <br />
    <div style="margin-top: 5px">
        <asp:Literal id="litStudentDetail" runat="server" />
    </div>
</asp:Content>

The code-behind file "StudentList.aspx" will be implemented as the following:

using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Data;
using System.Web.UI.WebControls;
using ASPNetMVCTutorial.Models;
using ASPNetMVCTutorial.Utilities;
 
namespace ASPNetMVCTutorial.Views.Students
{
    public class StudentList : System.Web.Mvc.ViewPage
    {
        protected Literal litStudentDetail;
        protected HyperLink linkAddStudent;
 
        protected void Page_Load(object sender, EventArgs e)
        {
            Response.Cache.SetCacheability(HttpCacheability.NoCache);
 
            linkAddStudent.NavigateUrl = 
                ApplicationUtility.FormatURL("/Students/AddStudent");
 
            DataTable StudentsTable = (DataTable)ViewData["Students"];
            DataView StudentsView = StudentsTable.DefaultView;
            StudentsView.Sort = "ID Desc";
 
            StringBuilder SB = new StringBuilder();
 
            SB.Append("<table style=\"width: 99%;\" ");
            SB.Append("rules=\"all\" border=\"1px\" ");
            SB.Append("cellspacing=\"0px\" cellpadding=\"4px\">");
 
            SB.Append("<tr style=\"background-color: Silver; color: white; ");
            SB.Append("font-weight: bold\">");
            foreach (DataColumn aColumn in StudentsTable.Columns)
            {
                SB.Append("<td>");
                SB.Append(aColumn.ColumnName);
                SB.Append("</td>");
            }
            SB.Append("<td> </td>");
            SB.Append("</tr>");
 
            foreach (DataRowView aRowView in StudentsView)
            {
                SB.Append("<tr>");
                foreach (DataColumn aColumn in StudentsTable.Columns)
                {
                    SB.Append("<td>");
                    SB.Append(aRowView[aColumn.ColumnName].ToString());
                    SB.Append("</td>");
                }
 
                string ID = aRowView["ID"].ToString();
                SB.Append("<td>");
                SB.Append("<a href=\"");
                SB.Append(ApplicationUtility.FormatURL("/Students/DeleteStudent"));
                SB.Append("?ID=");
                SB.Append(ID);
                SB.Append("\">Delete this student</a>");
                SB.Append("</td>");
                SB.Append("</tr>");
            }
 
            SB.Append("</table>");
 
            litStudentDetail.Text = SB.ToString();
        }
    }
}

Similarly we will implement the "AddStudent.aspx" to the "Views\Students" folder as the following:

<%@ Page Language="C#"
    MasterPageFile="~/Views/Shared/Site.Master"
    CodeBehind="~/Views/Students/AddStudent.aspx.cs"
    Inherits="ASPNetMVCTutorial.Views.Students.AddStudent" %>
 
<asp:Content ID="AddStudentContent" 
    ContentPlaceHolderID="ApplicationContent" runat="server">
<script language="javascript" type="text/javascript">
    function SubmitForm() {
        frmAddStudent.action = hidAddstudentActionURL.value;
        frmAddStudent.submit();
    }
</script>
 
<asp:Literal ID="litAddStudentActionHidden" runat="server" />
<form id="frmAddStudent" method="post" action="">
<div style="text-align: center">
    <table cellspacing="5px" cellpadding="0px" style="text-align: 
        center; margin-left:auto; margin-right:auto;">
        <tr>
            <td class="BoldText" style="text-align: left">
                Please provide the following information to add the student:
            </td>
        </tr>
        <tr><td style="height: 10px"></td></tr>
        <tr>
            <td>
                Name <input type="text" id="textName" name="textName" />
                  
                Score <input type="text" id="txtScore" name="txtScore" />
            </td>
        </tr>
        
        <tr>
            <td>
                <asp:HyperLink ID="linkCancelAddStudent" 
                    Text="Cancel add student and 
			return to the main page" runat="server" />
                <input type="button" value="Add student" onclick="return SubmitForm()" />
            </td>
        </tr>
    </table>
</div>
</form>
</asp:Content>

The code-behind file for the "AddStudent.aspx" view will be implemented as the following:

using System;
using System.Text;
using System.Web;
using System.Web.UI.WebControls;
using ASPNetMVCTutorial.Models;
using ASPNetMVCTutorial.Utilities;
 
namespace ASPNetMVCTutorial.Views.Students
{
    public class AddStudent : System.Web.Mvc.ViewPage
    {
        protected HyperLink linkCancelAddStudent;
        protected Literal litAddStudentActionHidden;
        protected void Page_Load(object sender, EventArgs e)
        {
            Response.Cache.SetCacheability(HttpCacheability.NoCache);
 
            StringBuilder SB = new StringBuilder();
            SB.Append("<input type=\"hidden\" id=\"hidAddstudentActionURL\" value=\"");
            SB.Append(ApplicationUtility.FormatURL("/Students/AddStudentAction"));
            SB.Append("\" />");
            linkCancelAddStudent.NavigateUrl
                = ApplicationUtility.FormatURL("/Students/StudentList");
            litAddStudentActionHidden.Text = SB.ToString();
        }
     }
}

The "Error.aspx" view will be implemented in the "Views\Shared" folder as the following:

<%@ Page Language="C#"
    CodeBehind="~/Views/Shared/Error.aspx.cs"
    MasterPageFile="~/Views/Shared/Site.Master" 
    Inherits="ASPNetMVCTutorial.Views.Shared.Error" %>
 
<asp:Content ID="ErrorContent" ContentPlaceHolderID="ApplicationContent" runat="server">
<div style="margin-top: 10px; text-align: center">
    <table cellpadding="4px" cellspacing="4px" style="margin-left:auto; 
	margin-right:auto;">
        <tr><td class="ErrorText"><asp:Literal ID="litErrorMessage" 
		runat="server" /></td></tr>
        <tr><td style="text-align: right">
            <asp:HyperLink ID="linkBackToMainPage" Text="Go back to main page" 
		runat="server" />
        </td></tr>
    </table>
</div>
</asp:Content>

The code-behind file for the "Error.aspx" will be implemented as the following:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI.WebControls;
using ASPNetMVCTutorial.Models;
using ASPNetMVCTutorial.Utilities;
 
namespace ASPNetMVCTutorial.Views.Shared
{
    public class Error : System.Web.Mvc.ViewPage
    {
        protected Literal litErrorMessage;
        protected HyperLink linkBackToMainPage;
 
        protected void Page_Load(object sender, EventArgs e)
        {
            Response.Cache.SetCacheability(HttpCacheability.NoCache);
 
            linkBackToMainPage.NavigateUrl
                = ApplicationUtility.FormatURL("/Students/StudentList");
            string ErrorMessage = ViewData["ERROR"].ToString();
            litErrorMessage.Text = ErrorMessage;
        }
    }
}

The ASP.NET MVC views are specialized ASP.NET pages. The "System.Web.Mvc.ViewPage" class is an immediate child class of the "System.Web.UI.Page" class in the class inheritance hierarchy. When developing the views, it is important to avoid any modifications to the application data to better conform to the MVC methodology.

Add a Controller to the "Controllers" Folder

Now we are ready to add the controller for this ASP.NET MVC project. Right click the "Controllers" folder to add the control class and name the class as "StudentsController" and implement this controller class as the following:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using ASPNetMVCTutorial.Models;
 
namespace ASPNetMVCTutorial.Controllers
{
    public class StudentsController : Controller
    {
        private StudentsModel GetStudentModelFromSession()
        {
            StudentsModel theModel = (StudentsModel)Session["Students"];
            if (theModel == null)
            {
                theModel = new StudentsModel();
                Session["Students"] = theModel;
            }
 
            return theModel;
        }
 
        public ActionResult StudentList()
        {
            StudentsModel theModel = GetStudentModelFromSession();
 
            ViewData["Students"] = theModel.GetStudents();
            return View();
        }
 
        public ActionResult AddStudent()
        {
            return View();
        }
 
        public ActionResult AddStudentAction()
        {
            string Name = Request.Form["textName"];
            string Score = Request.Form["txtScore"];
 
            if ((Name == null) || (Name.Trim() == ""))
            {
                ViewData["ERROR"] = "Please provide a name for the student to add";
                return View("../Shared/Error");
            }
 
            if (Name.Length < 6)
            {
                ViewData["ERROR"]
                    = "The student's name should not be less than 6 characters.";
                return View("../Shared/Error");
            }
  
            int intScore;
            if (!Int32.TryParse(Score, out intScore))
            {
                ViewData["ERROR"]
                    = "Please provide a valid score to the student to add.";
                return View("../Shared/Error");
            } 
 
            if ((intScore < 60) || (intScore > 100))
            {
                ViewData["ERROR"]
                    = "We only accept students with scores between 60 and 100.";
                return View("../Shared/Error");
            }
 
            StudentsModel theModel = GetStudentModelFromSession();
            theModel.AddStudent(Name, intScore);
 
            ViewData["Students"] = theModel.GetStudents();
            return View("StudentList");
        }
 
        public ActionResult DeleteStudent()
        {
            string ID = Request.QueryString["ID"];
            int intID;
 
            if (!Int32.TryParse(ID, out intID))
            {
                ViewData["ERROR"] = "Please provide a valid student ID";
                return View("../Shared/Error");
            }
 
            StudentsModel theModel = GetStudentModelFromSession();
            theModel.DeleteStudent(intID);
 
            return RedirectToAction("StudentList");
        }
    }
}

This controller is named as "StudentsController". It implements 5 methods.

The private method "GetStudentModelFromSession" is used to demonstrate how the web session is used in this ASP.NET MVC projects. It returns an object of type "StudentsModel", which is implemented in the "Models" folder. The method first tries to obtain this object from the web session. If it is unable to get it, it will create a new object and add it to the web session. This object will be used as the data storage in this tutorial web application.

The four public methods are called "actions" in the ASP.NET MVC terminology:

  • StudentList
  • AddStudent
  • AddStudentAction
  • DeleteStudent

These methods are used to perform certain operations on the application data saved in the web session. When the operations on the application data are completed, each method will choose a view implemented in the "Views" folder to display the data to the users. If the view of choice is the same name as the "action", the name of the view can be omitted. To access the user input from the browser, these methods can use the familiar "Request.QueryString' and "Request.Form" methods.

The action methods pass the data for the views to display by the "ViewData" dictionary.

"Global.asax" - Where the Magic Happens

When we create the ASP.NET MVC project, Visual Studio generates a default "Global.asax" file for us. Now we will make changes to this file to the following:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
 
namespace ASPNetMVCTutorial
{
    public class MvcApplication : System.Web.HttpApplication
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
 
            routes.MapRoute(
                "Default",
                "{controller}/{action}/{id}",
                new { controller = "Students", 
                    action = "StudentList", 
                    id = UrlParameter.Optional }
            );
        }
 
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
 
            RegisterRoutes(RouteTable.Routes);
        }
    }
}

The URLs to access the web pages developed in ASP.NET MVC projects are like "http://localhost/VirtualDirectoryName/Controller/Action". The calling of the "routes.MapRoute" method in the "Global.asax" file makes sure the correct controller and action are located. If the URL does not specify the controller and action, the controller "Student" and the action "StudentList" will be used as default.

When a URL is received by the web application, it will first find the controller. If the controller in the URL is "Student", the web application will try to locate a class named as "StudentController" in the "Controllers" folder. After the controller class is located, the method of the same name as the action, say "StudentList" is called. The chosen action method in the controller class will perform all the operations on the application data, and choose a view to display to the user. The action methods pass the data for the views to display by the "ViewData" dictionary.

If you want to mix regular "aspx" pages with the MVC views in the same ASP.NET project, you can add the following code before mapping the ASP.NET MVC routing:

routes.IgnoreRoute("{resource}.aspx/{*pathInfo}");  

This way, the routing will ignore the URLs pointing to regular "aspx" pages. These pages will be loaded directly without going through the controller-action-view pattern.

The Completed Project Shown in the Solution Explorer

Now we completed the development of this tutorial ASP.NET MVC application. The following picture shows all the files including the code-behind files in the solution explorer:

SolutionExplorerComplete.jpg

Run the ASP.NET MVC Application

Press "F5" when Visual Studio is having the focus, we can start to debug run the tutorial application. The following picture shows the application running in "Google Chrome":

RunApplicationList.jpg

Click on one of the "Delete this student" links, we can delete the student from the list. Click on the link "Click to add a student to the list", the web page is then navigated to the following:

RunApplicationAdd.jpg

Type in a student name and give the student a score, and click the "Add student" button, we can see that the student is added.

RunApplicationComplete.jpg

Points of Interest

  • This tutorial is intended for readers to get a quick start on developing ASP.NET MVC applications in Visual Studio. It may not follow Scott Guthrie, or even the general MVC exactly. If there are any differences, you should definitely go with Scott Guthrie.
  • Regarding if the code-behind files should be used in the views, I do not want to get into the discussion. I think it is better to leave this choice to the application developers. If the MVC pattern is to separate the concerns in the application development, why should we not further separate the concerns in the development of the views? In this tutorial, all the views have code-behind files.
  • It should be noted that the ASP.NET MVC pattern is different from the MVVM pattern in the WPF development. In MVVM, we have the more mature two-way databinding, which allows the MVVM to minimize the use of the code-behind file of a "xaml" file. But in the ASP.NET MVC pattern, the controllers pass the data for display by the "ViewData" dictionary to the views. In the views, if we do not use the code-behind files, we will need to use the in-line server scripts in the "aspx" files, which makes the unit testing of the views almost impossible.
  • The "Model" part of this MVC tutorial is a "DataTable" saved in the web session. By doing this, Visual Studio is the only thing needed for the readers to complete the tutorial. For any practical ASP.NET MVC application, persistent data storage will be needed.
  • The "FormatURL" method in the utility class "ApplicationUtility" is to make sure that we can always get the correct ASP.NET MVC pattern URL even when the virtual directory name is changed at the deployment time. There are many ways to achieve the same goal. If you do not like this method, you can always implement your own.
  • Developing applications running in the web browsers is a comprehensive task by nature. It is always better if you can combine all the available technologies, such as CSS style sheets, Javascripts, Ajax, jQuery, Silverlight, as well as the MVC pattern to give the best performance and user experiences.

Conclusion

To finish this tutorial, we will answer the questions listed at the beginning of the article:

  • How are the ASP.Net MVC URLs associated to the resources on the web server?
    • The URLs for an ASP.NET MVC application have a controller part and an action part, the application will use the controller part to locate the controller class and use the action part to locate the action method implemented in the controller class. When the action method finishes the operations on the application data, it will choose a view to display the application data.
  • In ASP.NET, what are the Models, Views, and Controllers and how are they implemented?
    • In a standard ASP.NET MVC application created by the Visual Studio, there are three folders named as "Models", "Views", and "Controllers". The models, views, and controllers will be implemented in the corresponding folders.
    • The models represent the applications data. In this tutorial, it is a "DataTable" to be saved in the application's web session.
    • The views are specialized ASP.NET "aspx" pages, the development of the views is very similar to the development of the "aspx" pages of the "System.Web.UI.Page type.
    • The controllers are classes that implements the actions. Each action will optionally perform some operations on the application data and choose a view to display the data.
  • How is information passed among the Models, Views, and Controllers?
    • How the controllers access the application data implemented in the models should be a design issue and should be decided by the application developers based on the business need.
    • The controllers can pass data for the views to display by "ViewData" dictionary.
  • How does the application code on the server access the data passed to the server by URL parameters and form submissions from the browser?
    • This tutorial demonstrated that the application can use the familiar "Request.QueryString and "Request.Form" to access the user input data. To conform to the MVC methodology, the user input data should be accessed in the controllers, but not in the views.
  • How to access the session data in ASP.NET MVC?
    • This tutorial demonstrated that web sessions can be used the same way when we develop the "aspx" pages of the "System.Web.UI.Page type. To conform to the MVC methodology, the session data should be accessed in the controllers, but not in the views.
  • How to use code-behind when implementing the Views?
    • In Visual Studio, the code-behind files for the views can be added manually. There is a hot discussion on if we should use code-behind files for the views, but if you like to use the code-behind files, you can add them anyway. If we do not use the code-behind files, we will need to use in-line server scripts in the views.

History

This is the first revision of the article.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here