Your First ASP.NET MVC Application
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
chapter describes how to use this template. We will briefl y 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 specifi c action method inside
a controller, and unit testing of a controller are also illustrated in this
chapter.
In this chapter, you will:
-
Receive an overview of all of the aspects of an ASP.NET MVC web application
-
Explore the ASP.NET MVC web application project template that is installed in
Visual Studio 2008
-
Create a fi rst action method and a corresponding view
-
Create a strong-typed view
-
Learn how a controller action method can pass strong-typed ViewData to the view
-
Learn what unit testing is all about, and why it should be performed
-
Learn 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
This exercise consists of the following major topics:
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 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.
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.
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?
Af ter 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. Th e
Controllers folder obviously contains all of the controller classes; th e
Models folder contains the model classes; wh ile the Views folder contains the
view pages. Co ntent will typically contain web site content such as images and
stylesheet fi les, and Scripts will contain all of the JavaScript fi les used
by the web application. By default, the Scripts folder contains some JavaScript
fi les required for the use of Microsoft AJAX or jQuery.
Locating the different building blocks is done in the request life cycle, which
is described in Chapter 4, Components in the ASP.NET MVC Framework. One of the
fi rst 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 fi le and describes
to the ASP.NET MVC framework how to handle a request. Double-clicking on the
Global.asax fi le in the MvcApplication1 project will display the following
code:
us ing 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 fi red 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 Hom e 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 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 Sh ow
action, and the firstname parameter. The following code snippet can be inserted
in the Global.asax fi le we've just opened. Because the ASP.NET MVC framework
uses the fi rst 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:
The EmployeeController class now looks like this:
usi ng 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.
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 t he 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.
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.
View s 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 fi rst 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.
usin g 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);
}
}
}
Creating a new view
Durin g 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:
In the Add view dialog box, some options can be specifi ed. First of all, the
view name can be modifi ed 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. You will see a little more
about this in Chapter 4, Components in the ASP.NET MVC Framework.
From t his 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 t esting 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.
Also read
The ASP.NET MVC framework was created to support pattern-based software
development. In other words, the framework was designed to make it easier to
implement software design principles and patterns when building web
applications..............
The ASP.NET MVC framework was released by Microsoft as an alternative approach
to web forms when creating ASP.NET based web applications. The ASP.NET MVC
framework is not a replacement or upgrade of web forms, but merely another way
of programming your web applications so that we can get the benefi ts of an MVC
design with much less effort.
The ASP.NET MVC framework was released by Microsoft as an alternative approach
to web forms when creating ASP.NET based web applications. The ASP.NET MVC
framework is not a replacement or upgrade of web forms, but merely another way
of programming your web applications so that we can get the benefi ts of an MVC
design with much less effort.
The Repeater, DataList, and DataGrid controls support event bubbling. What is
event bubbling? Event Bubbling refers to the ability of a control to capture
the events in a child control and bubble up the event to the container whenever
an event occurs........
One of the important goals of ASP.NET 2.0 is 70% code reduction. The data
controls supplied with ASP.NET 2.0 play an important role in making this
ambitious goal a reality. Data source controls provide a consistent and
extensible method for declaratively accessing data from web pages..............
One of the neat features of ASP.NET 2.0 is themes, which enable you to define
the appearance of a set of controls once and apply the appearance to your
entire web application............
ASP.NET 2.0 ships with a Web Parts Framework that provides the infrastructure
and the building blocks required for creating modular web pages that can be
easily customized by the users. You can use Web Parts to create portal pages
that aggregate different types of content, such as static text, links, and
content that can change at runtime..................
How do we access crystal reports in .NET?
What are the various components in crystal reports?
What basic steps are needed to display a simple report in crystal?..........
What is AppSetting Section in
“Web.Config” file?
AppSetting section is used to set the user defined values. For e.g.: The
ConnectionString which is used through out the project for database
connection.........
Difference between
Server.Transfer and response.Redirect.
Following are the major differences between Server.Transfer and
response.Redirect.....
|