Series Index
- Part 1: Introduction
- Part 2: ModelMetadata
- Part 3: Default Templates
- Part 4: Custom Object Templates
- Part 5: Master Page Templates
Introduction to Templates
One of the major new features in ASP.NET MVC 2 is templates.
This is a feature that’s similar to Dynamic Data for WebForms. Given an object of a given type, the system can automatically display or edit that object, whether it’s a simple data item (like an integer, a decimal, a string, etc.) or a complex data item (like a class).
Html.Display
To display an item, there are three Display method HTML helpers (each with a few overloads):
- String based: <%= Html.Display(“PropertyName”) %>
- Expression based: <%= Html.DisplayFor(model => model.PropertyName) %>
- Model: <%= Html.DisplayForModel() %>
The string-based versions can be used to pull things to be displayed from both ViewData and a model (whose exact type you may not know).
The expression-based versions are primarily used for pulling values from the model (they are parametrized by the current model, as shown in the example above). They can also be used for pulling values from some source other than the model or ViewData (for example, with an expression like “model => someOtherValue” which ignores the model entirely). This makes them useful in loops.
The model expressions are simple helpers which operate on the current model. The line DisplayForModel() is equivalent to DisplayFor(model => model).
Let’s start off with a model:
public class Contact { public string FirstName { get; set; } public string LastName { get; set; } public int Age { get; set; } }
and an action:
public ViewResult Details([DefaultValue(0)] int id) { return View(contacts[id]); }
and a view:
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.master" Inherits="System.Web.Mvc.ViewPage" %> <asp:Content ContentPlaceHolderID="MainContent" runat="server"> <%= Html.DisplayForModel() %> </asp:Content>
Running the action yields this result:
Html.Editor
As with Html.Display, there are three versions of Html.Editor, which are used to edit objects:
- String based: <%= Html.Editor(“PropertyName”) %>
- Expression based: <%= Html.EditorFor(model => model.PropertyName) %>
- Model: <%= Html.EditorForModel() %>
If I change my view from DisplayForModel to EditorForModel, this is what I’ll see:
Now we can see that, for strings and integers, the system will provide text box editors automatically for us.
What’s Really Happening?
The template system in MVC 2 contains several built-in templates.
The first one we’re seeing in action here is the complex object template. In order to “display” or “edit” a complex object, the system actually uses reflection to find all the properties on that object, and then automatically generates labels and displays/editors for each of those properties.
If we were to write the core logic for this, it might look something like this:
<% foreach (var prop in ViewData.ModelMetadata.Properties) { %> <div class="display-label"><%= prop.GetDisplayName() %></div> <div class="display-field"><%= Html.Display(prop.PropertyName) %></div> <% } %>
Note that this is nowhere near a complete implementation; I’ll talk about some of what’s missing in a later blog post.
That is the core of the complex object display template: loop over all the properties of the current model, and for each of those properties, show its label and then call Html.Display() to display the actual property value.
What happens when we want to display a string? This is roughly the view code for that:
<%= Html.Encode(Model) %>
Again, this is not the actual code, but we will see what the real code is in a later blog post.
Overriding Templates
There is a lot of value in having a bunch of templates built-in, but the bigger value is in being able to override the template at any point in the rendering process.
Here, I’m going to override the display template for strings by creating a partial view named String inside of ~/Views/ControllerName/DisplayTemplates:
And inside this file, I write:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %> <%= Html.Encode(Model) %> Hello there!
Now I refresh the page and see:
You can see that we’ve picked up the new template automatically, and it’s being used for all of our strings. It’s also being used for the integer Age, but we’ll cover why that is in a later blog post.
If we want to write a template for editors, then you place it in a folder named EditorTemplates.
Wrapping Up
We have a lot to learn about this new Templates feature in ASP.NET MVC 2. This post has introduced us to the template concept and shown us how we can override the built-in templates. In the next blog post, we’ll talk about what the ModelMetadata class is and how it affects templates, as well as the DataAnnotations attributes that feed into ModelMetadata by default in ASP.NET MVC 2.