Customizing and Extending the ASP.NET MVC Framework

by Maarten Balliauw | March 2009 | Microsoft

One of the driving goals for the ASP.NET MVC framework has been to create a flexible framework in which every component can be extended or replaced by a custom solution, whether developed by you or obtained from a third-party vendor. In this article by Maarten Balliauw, you will learn how you can customize and extend the ASP.NET MVC framework.

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

Creating a control

When building applications, you probably also build controls. Controls are re-usable components that contain functionality that can be re-used in different locations. In ASP.NET Webforms, a control is much like an ASP.NET web page. You can add existing web server controls and markup to a custom control and define properties and methods for it. When, for example, a button on the control is clicked, the page is posted back to the server that performs the actions required by the control.

The ASP.NET MVC framework does not support ViewState and postbacks, and therefore, cannot handle events that occur in the control. In ASP.NET MVC, controls are mainly re-usable portions of a view, called partial views, which can be used to display static HTML and generated content, based on ViewData received from a controller. In this topic, we will create a control to display employee details. We will start by creating a new ASP.NET MVC application using File | New | Project... in Visual Studio, and selecting ASP.NET MVC Application under Visual C# - Web. First of all, we will create a new Employee class inside the Models folder. The code for this Employee class is:

public class Employee
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public string Department { get; set; }
}

On the home page of our web application, we will list all of our employees. In order to do this, modify the Index action method of the HomeController to pass a list of employees to the view in the ViewData dictionary. Here's an example that creates a list of two employees and passes it to the view:

public ActionResult Index()
{
ViewData["Title"] = "Home Page";
ViewData["Message"] = "Our employees welcome you to our site!";
List<Employee> employees = new List<Employee>
{
new Employee{
FirstName = "Maarten",
LastName = "Balliauw",
Email = "maarten@maartenballiauw.be",
Department = "Development"
},
new Employee{
FirstName = "John",
LastName = "Kimble",
Email = "john@example.com",
Department = "Development"
}
};
return View(employees);
}

The corresponding view, Index.aspx in the Views | Home folder of our ASP.NET MVC application, should be modified to accept a List<Employee> as a model. To do this, edit the code behind the Index.aspx.cs file and modify its contents as follows:

using System.Collections.Generic;
using System.Web.Mvc;
using ControlExample.Models;
namespace ControlExample.Views.Home
{
public partial class Index : ViewPage<List<Employee>>
{
}
}

In the Index.aspx view, we can now use this list of employees. Because we will display details of more than one employee somewhere else in our ASP.NET MVC web application, let's make this a partial view.

Right-click the Views | Shared folder, click on Add | New Item... and select the MVC View User Control item template under Visual C# | Web | MVC. Name the partial view, DisplayEmployee.ascx.

ASP.NET MVC 1.0 Quickly

The ASP.NET MVC framework provides the flexibility to use a strong-typed version of the ViewUserControl class, just as the ViewPage class does. The key difference between ViewUserControl and ViewUserControl<T>is that with the latter, the type of view data is explicitly passed in, whereas the non-generic version will contain only a dictionary of objects. Because the DisplayEmployee.aspx partial view will be used to render items of the type Employee, we can modify the DisplayEmployee. ascx code behind the file DisplayEmployee.ascx.cs and make it strong-typed:

using ControlExample.Models;
namespace ControlExample.Views.Shared
{
public partial class DisplayEmployee :
System.Web.Mvc.ViewUserControl<Employee>
{
}
}

In the view markup of our partial view, the model can now be easily referenced. Just as with a regular ViewPage, the ViewUserControl will have a ViewData property containing a Model property of the type Employee. Add the following code to DisplayEmployee.ascx:

<%@ Control Language="C#" AutoEventWireup="true"
CodeBehind="DisplayEmployee.ascx.cs"
Inheits="ControlExample.Views.Shared.DisplayEmployee" %>
<%=Html.Encode(Model.LastName)%>, <%=Html.Encode(Model.FirstName)%>
<br/>
<em><%=Html.Encode(Model.Department)%></em>

The control can now be used on any view or control in the application. In the Views | Home | Index.aspx view, use the Model property (which is a List<Employee>) and render the control that we have just created for each employee:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.
Master" AutoEventWireup="true" CodeBehind="Index.aspx.cs"
Inherits="ControlExample.Views.Home.Index" %>
<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent"
runat="server">
<h2><%= Html.Encode(ViewData["Message"]) %></h2>
<p>Here are our employees:</p>
<ul>
<% foreach (var employee inModel) { %>
<li>
<% Html.RenderPartial("DisplayEmployee", employee); %>
</li>
<% } %>
</ul>
</asp:Content>

In case the control's ViewData type is equal to the view page's ViewData type, another method of rendering can also be used. This method is similar to ASP.NET Webforms controls, and allows you to specify a control as a tag. Optionally, a ViewDataKey can be specified. The control will then fetch its data from the ViewData dictionary entry having this key.

<uc1:EmployeeDetails ID="EmployeeDetails1"
runat="server"
ViewDataKey="...." />

For example, if the ViewData contains a key emp that is filled with an Employee instance, the user control could be rendered using the following markup:

<uc1:EmployeeDetails ID="EmployeeDetails1"
runat="server"
ViewDataKey="emp" />

After running the ASP.NET MVC web application, the result will appear as shown in the following screenshot:

ASP.NET MVC 1.0 Quickly

Sign up for a Packt account to see the rest of this article

Now that you've read a few articles, you might want to consider signing up for a Packt account. It takes a matter of seconds, will give you access to all the articles on PacktPub.com, and once you've signed up you'll be returned here to carry on reading your article.

Furthermore, you'll gain access to nine free ebooks, and be offered a free trial of PacktLib, Packt's online library. Simply enter your details here, or log in to your existing account.

Log in

...or register

Post new comment

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
Sort A-Z