Шаблоны отображения и редактирования — очень мощная и полезная фича ASP.Net MVC, которую я активно использую и рекомендую всем без исключения.
С помощью шаблонов можно легко и быстро отображать и редактировать модели данных, что весьма способствует быстрому прототипированию, а также помогает в случаях, когда внешний вид форм на сайте у вас более-менее стандартизован.
Предположим, что в контроллере у вас есть типичная модель регистрации:
public class RegistrationModel {
public string Login { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime Birthdate { get; set; }
...
}
Что вам нужно сделать, чтобы отобразить эту форму на сайте?
Обычно, что-то вроде:
@using (Html.BeginForm())
{
<div>
Login <br />@Html.TextBoxFor(x => x.Login)<br />
Firstname <br />@Html.TextBoxFor(x => x.FirstName)<br />
Lastname <br />@Html.TextBoxFor(x => x.LastName)<br />
Birthdate <br />@Html.TextBoxFor(x => x.Birthdate)<br />
<input type="submit" />
</div>
}
При этом получим мы что-то вроде:

С помощью шаблонов редактирования, код вьюшки можно свести к одной строчке:
@using (Html.BeginForm())
{
@Html.EditorForModel()
<input type="submit" />
}
Результат в браузере при этом будет фактически такой же.
То же верно и для отображения данных формы (без возможности редактирования). Имея во вьюшке всего одну строчку:
@Html.DisplayForModel()
У вас в модели есть поле ID, которое отображать не нужно, а при редактировании оно должно быть Hidden? Нет ничего проще!
public class RegistrationModel {
[HiddenInput(DisplayValue = false)]
public int ID { get; set; }
public string Login { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
...
}
При использовании шаблонов отображения/редактирования MVC проходится по всем полям вашей модели и последовательно выводит имена полей и соответствующие значения или input’ы для редактирования.
Если в некоторых случаях для определенных полей нет необходимости отображать label’ы, то можно сделать так:
public class RegistrationModel {
[HiddenInput(DisplayValue = false), UIHint("")]
public int ID { get; set; }
public string Login { get; set; }
}
Если это выглядит слегка неочевидно, то можно объявить свой атрибут:
public class RegistrationModel
{
[DisplayLabel(false)]
public string Login { get; set; }
}
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class DisplayLabelAttribute : Attribute, IMetadataAware
{
private readonly bool _visible;
public DisplayLabelAttribute(bool visible)
{
_visible = visible;
}
public void OnMetadataCreated(ModelMetadata metadata)
{
metadata.HideSurroundingHtml = !_visible;
}
}
Огромный плюс шаблонов в том, что в них настраивается практически всё. Не нравится отображение полей формы «в столбик», а хочется табличного вида вроде этого:

Просто переопределите шаблон отображения для типа Object! Для этого нужно создать папку DisplayTemplates (или EditorTemplates для шаблонов редактирования) в папке ~/Views/Shared (или ~/Views/ControllerName/Shared) и создайте там файл Object.cshtml:
@if (ViewData.TemplateInfo.TemplateDepth > 5)
{
if (Model == null)
{
@ViewData.ModelMetadata.NullDisplayText
}
else
{
@ViewData.ModelMetadata.SimpleDisplayText
}
}
else
{
<table cellpadding="0" cellspacing="0" border="0">
@foreach (var prop in ViewData.ModelMetadata.Properties.Where(pm => pm.ShowForDisplay
&& !ViewData.TemplateInfo.Visited(pm)))
{
if (prop.HideSurroundingHtml)
{
@Html.Editor(prop.PropertyName)
}
else
{
<tr>
<td>
<div class="display-label" style="text-align: right;">
@prop.GetDisplayName()
</div>
</td>
<td width="10">
</td>
<td>
<div class="display-field">
@Html.Editor(prop.PropertyName)
</div>
</td>
</tr>
}
}
</table>
}
Аналогично можно переопределить шаблоны и для любого другого типа, то есть использовав на стадии прототипирования @Html.EditorForModel() для отображения RegistrationModel мы можем в дальнейшем просто создать файл RegistrationModel.cshtml в папке EditorTemplates (строготипизировав его от типа RegistrationModel)- и получить кастомный шаблон редактирования/отображения, который будет содержать нужный нам GUI.
Использовать шаблоны также очень удобно в случае сложных вложенных форм:
public class OrderTicketsModel
{
public RegistrationModel FirstPassenger { get; set; }
public RegistrationModel SecondPassenger { get; set; }
}
Такую, казалось бы сложную, модель шаблонизатор тоже достаточно неплохо отрисовывает:

Наконец, как еще одно из применений шаблонизаторов, можно выделить создание собственных визуальных контролов для отображения стандартных элементов.
Например, посмотрим, как отображается по умолчанию enum:
public enum Sex
{
Male,
Female
}
public class Model2
{
public Sex Sex { get; set; }
}
public ActionResult Index2()
{
return View(new Model2());
}

Вводить текст в данном случае кажется совсем не удобным. Логично сделать выбор через RadioButton или DropDownList, правда?
Пример шаблона Enum_AsDropDownList.cshtml:
@model Enum
@{
// Looks for a [Display(Name="Some Name")] or a [Display(Name="Some Name", ResourceType=typeof(ResourceFile)] Attribute on your enum
var listItems = Enum.GetValues(Model.GetType()).OfType<Enum>().Select(e =>
new SelectListItem()
{
Text = e.GetDescription(),
Value = e.ToString(),
Selected = e.Equals(Model)
});
string prefix = ViewData.TemplateInfo.HtmlFieldPrefix;
ViewData.TemplateInfo.HtmlFieldPrefix = string.Empty;
@Html.DropDownList(prefix, listItems)
}
Применить шаблон к нашей модельке очень просто:
public class Model2
{
[UIHint("Enum_AsDropDownList")]
public Sex Sex { get; set; }
}
И выглядеть это будет как-то так:

Пример для радио баттонов, а также все предыдущие примеры можно посмотреть «в живую» на небольшом тестовом проекте.
Все полученные формы достаточно легко стилизовать при помощи css.
Итак, в каких же случаях это действительно удобно?
- Прототипирование. Когда вас не слишком заботит внешний вид приложения, а нужно продемонстрировать функционал — использование шаблонов позволит сэкономить время и легко преобразовать «тестовый проект» в реальное приложение в дальнейшем — потребуется только добавление кастомных файлов шаблона
- Значительное количество однотипных по формату отображения форм. В этом случае затраты на однократное переопределение шаблона для типа Object вполне окупается
- Создание визуальных «контролов» для типизированного отображения некоторых объектов доменной области — в данном случае удобство продиктовано «коробочностью» решения. Аналогом может служить создание html-хэлперов для отображения таких объектов, но придется каждый раз вспоминать имя функции, которое отобразило бы объект :) В случае шаблонов стандартный подход: @Html.EditorFor(x => x.FirstPassenger) универсален
В каких же случаях использовать шаблоны не стоит? В основном, это те случаи, когда отображения нешаблонное и повторное его использование не подразумевается: форма отображается только на одном экране, или в зависимости от экранов она выглядит очень по-разному. В этом случае внесение дополнительной сложности в виде разделения экрана на два файла (вьюшка и display/editor шаблон для формы) не имеет большого смысла.
Однако, хотя использование шаблонов для форм целиком в этом случае и не оправданно, вполне можно использовать в рамках таких форм шаблоны для отдельных элементов моделей (например, для отображения enum’а, как было показано выше).
Эта заметка — лишь краткое вступление в функционал шаблонов редактирования/отображения. Если вам понравилась идея и хочется узнать больше о тонкостях реализации, увидеть шаблоны по-умолчанию для различных типов, встроенные в MVC, посмотреть на другие варианты применения — добро пожаловать в первоисточник или его русифицированный вариант.
Тестовый проект со всем упомянутым выше: DisplayEditorTemplatesForBlog.zip

Унылое говно эти твои шаблоны :)
Кажется, ты еще забыл сказать, что аннотации типа «[UIHint]», «[HiddenInput]» и прочее тоже отстой :)
Я подразумевал :)