Recently, I noticed a nice pattern in the Nerd Dinner application. Nerd Dinner uses strongly typed view model classes to pass data from a controller to a view. This pattern provides you with a convenient way of representing complex view data.
Note: If you haven’t downloaded the Nerd Dinner sample ASP.NET MVC application yet, you really should. It is a really easy to understand sample application that you can use as a great introduction to ASP.NET MVC. You can download it from the http://www.ASP.net/mvc page.
In an ASP.NET MVC application, you pass data from a controller to a view by using view data. There are two ways that you can use view data. First, you can use view data as an untyped dictionary. For example, the controller in Listing 1 returns a collection of products in its Index() action. And, the view in Listing 2 displays the collection by iterating through each item in the collection.
Listing 1 – Controllers\ProductController.cs
using System.Collections.Generic;
using System.Web.Mvc;
using MvcApplication1.Models;
namespace MvcApplication1.Controllers
{
public class ProductController : Controller
{
//
// GET: /Product/
public ActionResult Index()
{
// Create list of products
var products = new List<Product>();
products.Add(new Product("Laptop computer", 344.78m));
products.Add(new Product("Bubble gum", 2.00m));
products.Add(new Product("Toothpaste", 6.99m));
// Add products to view data
ViewData["products"] = products;
// Return view
return View();
}
}
}
Listing 2 – Views\Product\Index.aspx
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
<%@ Import Namespace="System.Collections.Generic" %>
<%@ Import Namespace="MvcApplication1.Models" %>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<% foreach (var item in (List<Product>)ViewData["products"])
{ %>
<li> <%= item.Name %> </li>
<% } %>
</asp:Content>
The view in Listing 2 is an untyped view. Notice that the products item from view data must be cast to a collection of product items before you can do anything with it.
Instead of using an untyped view, you can use a strongly-typed view. The controller in Listing 3 also returns a collection of products. However, in this case, the collection is assigned to the ViewData.Model property.
Listing 3 – Controllers\Product2Controller.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using MvcApplication1.Models;
namespace MvcApplication1.Controllers
{
public class Product2Controller : Controller
{
//
// GET: /Product2/
public ActionResult Index()
{
// Create list of products
var products = new List<Product>();
products.Add(new Product("Laptop computer", 344.78m));
products.Add(new Product("Bubble gum", 2.00m));
products.Add(new Product("Toothpaste", 6.99m));
// Add products to view data
ViewData.Model = products;
// Return view
return View();
}
}
}
Listing 4 – Views\Product2\Index.aspx
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<MvcApplication1.Models.Product>>" %>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<% foreach (var item in Model)
{ %>
<li> <%= item.Name %> </li>
<% } %>
</asp:Content>
In Listing 3, the products are assigned to the ViewData.Model property. As an alternative to explicitly assigning data to the ViewData.Model property, you can pass the data to the View() method. In other words, the following two code blocks are equivalent:
// Assign products to Model
ViewData.Model = products;
return View();
// Assign products to Model
return View(products);
The view in Listing 4 is a typed view. In Listing 4, the Model property represents the collection of products as a collection of products. In other words, you don’t need to cast the view data to a collection of product items before you use the Model property.
Notice the Inherits attribute in the <%@ Page %> directive. The Inherits attribute is used to cast the Model property to a strongly-typed collection of product items. It looks like this:
<%@ Page Inherits="System.Web.Mvc.ViewPage<IEnumerable<MvcApplication1.Models.Product>>" %>
Kind of a mouthful, but it is clear what it means.
The easiest way to add a typed view into an ASP.NET MVC application is to right-click a controller action and select the menu option Add View. You can specify the type of the view in the Add View dialog (see Figure 1).
Figure 1 – Specifying the type of a view

Notice that, in Figure 1, I specified the view content as a List. Selecting this option results in a strongly-typed view that represents a collection of products. If I had picked Empty instead of List, then I would get a strongly-typed view that represents a single product.
In general, I prefer using typed views instead of untyped views. To my eyes, performing casts within a view looks ugly.
The view data class exposes only one Model property. So what do you do when you need to pass multiple data items from a controller to a view? For example, how do you pass both a collection of products and collection of product categories to a view using a typed view? The answer is to use a view model.
The controller in Listing 5 contains a class named ProductViewModel. This class exposes a property for both the collection of products and the collection of categories. And, the strongly-typed view in Listing 6 displays both the products and product categories.
Listing 5 – Controllers\Product3Controller.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using MvcApplication1.Models;
namespace MvcApplication1.Controllers
{
// View Model Classes
public class ProductViewModel
{
public ProductViewModel(List<Product> products, List<Category> categories)
{
this.Products = products;
this.Categories = categories;
}
public List<Product> Products { get; private set; }
public List<Category> Categories { get; private set; }
}
// Controller Class
public class Product3Controller : Controller
{
//
// GET: /Product3/
public ActionResult Index()
{
// Create list of products
var products = new List<Product>();
products.Add(new Product("Laptop computer", 344.78m));
products.Add(new Product("Bubble gum", 2.00m));
products.Add(new Product("Toothpaste", 6.99m));
// Create list of categories
var categories = new List<Category>();
categories.Add(new Category("Electronics"));
categories.Add(new Category("Household"));
// Return view
return View( new ProductViewModel(products, categories));
}
}
}
Listing 6 –Views\Product3\Index.aspx
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MvcApplication1.Controllers.ProductViewModel>" %>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Categories</h2>
<% foreach (var item in Model.Categories)
{ %>
<li> <%= item.Name %> </li>
<% } %>
<h2>Products</h2>
<% foreach (var item in Model.Products)
{ %>
<li> <%= item.Name %> </li>
<% } %>
</asp:Content>
You can create the view in Listing 6 by selecting ProductViewModel as the data class when adding the view (see Figure 2).
Figure 2 – Adding a strongly-typed view with a ProductViewModel

The pattern that I like here is the pattern of defining the view model in the controller class. The view model is directly related to the controller actions, so it makes sense to define the view model here (in the past, I had created view model classes as separate classes in my Models folder).