Переопределение шаблонов отображения и редактирования

Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core

Последнее обновление: 31.10.2015

При использовании методов DisplayFor()/EditorFor() фреймворк MVC сам определяет, каким образом и какую разметку html создавать для отображения и редактирования полей модели. Но мы можем переопределить подобное поведение, указав, как именно MVC должен работать с отдельными типами данных.

Допустим, у нас есть следующая модель:

public class Book
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
}

Модель содержит свойства трех типов данных: int, string, decimal. Переопределим создание разметки для этих свойств.

Для этого добавим в проект в каталог Views/Shared две новых папки: DisplayTemplates (для шаблонов отображения) и EditorTemplates (для шаблонов редактирования):

Display and Editor Templates in ASP.NET MVC 5

Так как класс использует свойства трех разных типов данных, в шаблонах отображения в папке DisplayTemplates я создал по файлу для каждого типа. Названия файлов носят названия классов, которые представляют данный тип. Например, файл Int32.cshtml, который используется для визуализации значений int, имеет следующую разметку:

@model Int32

<b>@Model</b>

Директива @model Int32 указывает, что в качестве модели будет использоваться тип int или Int32. А само содержимое модели делается жирным шрифтом с помощью тега <b>

Файл String.cshtml имеет следующее содержимое:

@model String

<b>"@Model"</b>

Тут тоже самое, только название указывается в кавычках. В общем-то мы можем определить разные теги или структуру тегов, можно, например, задать классы (<span class="string">"@Model"</span>) и т.д.

Файл Decimal.cshtml:

@model decimal

@{
    IFormatProvider formatProvider =
        new System.Globalization.CultureInfo("ru-RU");
    <span class="currency">@Model.ToString("C", formatProvider)</span>
}

Здесь уже определяется логика форматирования значения в качестве денежной единицы.

Теперь если мы используем хелпер DisplayFor() для вывода свойств модели:

@model CustomDisplayEditorTemplates.Models.Book

@{
    ViewBag.Title = "Display";
}

<h2>Display</h2>

<div>
    <div>
        <p>
            Id: @Html.DisplayFor(model => model.Id)
        </p>
        <p>
            Название: @Html.DisplayFor(model => model.Name)
        </p>
        <p>
            Цена: @Html.DisplayFor(model => model.Price)
        </p>

    </div>
</div>

То мы получим следующую картину:

В папку EditorTemplates я добавил только один шаблон форматирования - String.cshtml:

@model string

<input type="text" name="name" style="border-color:red; height:40px; background-color:#eee;" value="@Model" />

И допустим, у нас есть следующее представление для редактирования данных:

@model CustomDisplayEditorTemplates.Models.Book

@{
    ViewBag.Title = "Edit";
}

<h2>Edit</h2>

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()
    @Html.HiddenFor(model => model.Id)
    <p>Название: @Html.EditorFor(model => model.Name)</p>
    <p>Цена: @Html.EditorFor(model => model.Price)</p>
    <p><input type="submit" value="Сохранить" /></p>
}

То мы получим следующую страницу:

При создании подобных шаблонов на основе элементов ввода следует учитывать их ограниченность: в данном случае элемент имеет атрибут name="name", поэтому его значение будет сопоставляться со свойством Name. Если у нас она модель в которой есть только одно строковое свойство, которое называется Name, то подобный подход еще сработает. Но у нас может быть несколько свойств с типом string, которые могут называться по-разному. В этом случае мы можем определить шаблон вывода или редактирования модели целиком.

Например, добавим в папку DisplayTemplates следующий файл Book.cshtml:

@model CustomDisplayEditorTemplates.Models.Book

<table>
    <tr><td>Id:</td><td>@Model.Id</td></tr>
    <tr><td>Название:</td><td>@Model.Name</td></tr>
    <tr><td>Цена:</td><td>@Model.Price рублей</td></tr>
</table>

CustomDisplayEditorTemplates - в данном случае это название моего проекта, в котором определен класс Book.

Значения всех свойств модели выводятся через таблицу. Тогда представление для отображения модели будет выглядеть так:

@model CustomDisplayEditorTemplates.Models.Book
@{
    Layout = null;
}
@Html.DisplayForModel()

Также добавим в каталог EditorTemplates шаблон для редактирования Book.cshtml:

@model CustomDisplayEditorTemplates.Models.Book

@using (Html.BeginForm())
{
    @Html.HiddenFor(model => model.Id)
    <table>
        <tr><td>Название: </td><td><input type="text"  name="name" value="@Model.Name" /></td></tr>
        <tr><td>Цена: </td><td><input type="text" name="price" value="@Model.Price" /></td></tr>
        <tr><td><input type="submit" value="Сохранить" /></td><td></td></tr>
    </table>
}

Используем этот шаблон для создания формы редактирования:

@model CustomDisplayEditorTemplates.Models.Book

@{
    Layout = null;
}
@Html.EditorForModel()
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850