Use display and editor templates FTW!

Use display and editor templates FTW!

Display and editor templates in ASP.NET MVC are often overlooked and are in fact quite powerful, here's why I think they are awesome.

Background

Display and editor templates were introduced in MVC 2 as a way to automatically build UI based on a data model. Essentially, it allows us a way to return markup required to display the data for the specified model. This is awesome because we can create templates for commonly used data models, allowing reuse and a clean razor view. The difference between display and editor templates are:

  • Display templates are used for read-only HTML elements.
  • Editor templates are used for editable HTML elements (e.g. input fields).

The syntax to use a template in our Razor view typically looks like this:

@Html.DisplayFor(x => x.User)

or

@Html.EditorFor(x => x.User)

Using templates

Let's create a display template and an editor template for an existing type; DateTime.

Display templates

On our site we want all our DateTime values to be short date format, a display template can do this for us. In views > shared create a folder called DisplayTemplates, adding a file called DateTime.cshtml.

Display template folder and file

This is our display template. The template is named by the type, this is the default convention for MVC. Whatever we add to this view will be used for the DateTime type.

@model System.DateTime
@Model.ToShortDateString()

Now whenever we have a DateTime property we just need to use DisplayFor() in our view.

@Html.DisplayFor(x => x.User.DateOfBirth)

Editor templates

Editing a DateTime value requires a completely different set of HTML elements, but we can create a template for this too. In views > shared create a folder called EditorTemplates, adding a file called DateTime.cshtml. Again the template is named after the type.

Editor template folder and file

Adding the following code:

@model System.DateTime
@Html.DropDownListFor(model => model.Day, Enumerable.Range(1, 31).Select(i => new SelectListItem { Value = i.ToString(), Text = i.ToString() }), "Day")
@Html.DropDownListFor(model => model.Month, Enumerable.Range(1, 12).Select(i => new SelectListItem { Value = i.ToString(), Text = System.Globalization.CultureInfo.InvariantCulture.DateTimeFormat.GetMonthName(i) }), "Month")
@Html.DropDownListFor(model => model.Year, Enumerable.Range(1900, 115).Select(i => new SelectListItem { Value = i.ToString(), Text = i.ToString() }), "Year")

This will render three dropdown elements for day, month, year. This time we use EditorFor to render the property.

@Html.EditorFor(x => x.User.DateOfBirth)

UIHint

Now what if we want a couple of different templates for DateTime? Instead of naming the template after the type we can give it any name and use the UIHint attribute. We will create another display template and call it VerboseDateTime, adding:

@model System.DateTime
@Model.ToString("dddd, d, MMMM, yyyy") // "Saturday, 27, December, 2014"

Then decorate the property with the UIHint attribute specifying the template name.

[UIHint("VerboseDateTime")]
public DateTime DateOfBirth { get; set; }

And now we get our verbose output!

Summary

Display and editor templates allow us to create default UI markup for types or create special case templates. Think of this as a way of creating a framework for HTML representations of C# types. Much in the same way that Twitter Bootstrap is a framework for the styling of DOM elements.