Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core
Как мы увидели из прошлых примеров, представления используют разметку html для визуализации содержимого. Однако фреймворк ASP.NET MVC обладает также таким мощным инструментом как HTML-хелперы, позволяющие генерировать html-код.
Строчные хелперы похожи на обычные определения методов на языке C#, только начинаются с тега @helper
. Например, создадим в представлении
хелпер для вывода названий книг в виде списка:
@helper BookList(IEnumerable<BookStore.Models.Book> books) { <ul> @foreach (BookStore.Models.Book b in books) { <li>@b.Name</li> } </ul> }
Данный хелпер мы можем определить в любом месте представления. И также в любом месте представления мы можем его использовать, передавая в него объект IEnumerable<BookStore.Models.Book>:
<h3>Список книг</h3> @BookList(ViewBag.Books) <!-- или если используется строго типизированное представление --> @BookList(Model)
Строчные html-хелперы удобно использовать, если необходимо создать один метод, который предполагается использовать в представлении многократно. Например:
@helper CreateList(string[] all) { <ul> @foreach (string s in all) { <li>@s</li> } </ul> } @{ string[] cities = new string[] { "Лондон", "Париж", "Москва" }; } @{ string[] countries = new string[] { "Великобритания", "Франция", "Россия" }; } <h3>Города</h3> @CreateList(cities) <br /> <h3>Страны</h3> @CreateList(countries)
При отсутствии подобного хелпера, то нам бы пришлось по сути дублировать один и тот же html-код для создания списка. Однако этот хелпер еще довольно простой, а если нам приходится создавать по сто раз более сложную, но однотипную разметку html, тогда хелперы окажутся еще более полезными.
Но данный подход имеет один недостаток - если хелпер очень объемный, то он может очень сильно захламлять разметку представления. И в этом случае его лучше вынести в отдельный файл кода. Для этого создадим в проекте папку под названием App_Code. "App_Code" - это специальное зарезервированное имя для папки, которая содержит html-хелперы, поэтому мы должны использовать данное название.
Далее добавим в эту папку новый файл - представление под названием MyHelpers.cshtml. В этом файле определим код хелпера:
@helper HtmlList(string[] items) { <ul> @foreach (var item in items) { <li>@item</li> } </ul> }
И затем мы сможем применить этот хелпер в любом представлении в нашем проекте:
@MyHelpers.HtmlList(new string[] { "Лондон", "Париж", "Берлин" })
Также для определения хелпера мы можем использовать стандартные классы на C#. Для этого нам надо создать новый класс с методом расширения - то есть таким методом, который расширяет функциональность уже существующих классов. А эти классы указываются в качестве первого параметра метода. Итак, создадим в проекте новую папку Helpers и добавим в нее новый класс ListHelper:
using System; using System.Web; using System.Web.Mvc; using System.Linq; namespace BookStore.Helpers { public static class ListHelper { public static MvcHtmlString CreateList(this HtmlHelper html, string[] items) { TagBuilder ul = new TagBuilder("ul"); foreach (string item in items) { TagBuilder li = new TagBuilder("li"); li.SetInnerText(item); ul.InnerHtml += li.ToString(); } return new MvcHtmlString(ul.ToString()); } } }
В новом классе хелпера определен один статический метод CreateList, принимающий в качестве первого параметра объект, для которого создается метод. Так как данный метод расширяет функциональность html-хелперов, которые представляет класс HtmlHelper, то именно объект этого типа и передается в данном случае в качестве первого параметра. Второй параметр метода CreateList - массив строк-значений, которые потом будут выводиться в списке.
В самом методе с помощью объекта TagBuilder конструируется стандартный элемент html - элемент ul. При обходе массива все строковые значения обертываются в тег li и добавляются в список. И на выходе возвращается полноценные элемент ul.
Класс TagBuilder имеет ряд членов, которые можно использовать при таком подходе:
Свойство InnerHtml позволяет установить или получить содержимое тега в виде строки
Метод MergeAttribute (string, string, bool) позволяет добавить к элементу один атрибут. Для получения всех атрибутов можно использовать коллекцию Attributes
Метод SetInnerText(string) устанавливает текстовое содержимое внутри элемента
Метод AddCssClass(string) добавляет класс css к элементу
После создания нового хелпера мы его можем использовать в представлении. Перепишем предыдущий пример следующим образом:
@{ string[] cities = new string[] { "Лондон", "Париж", "Москва" }; } @{ string[] countries = new string[] { "Великобритания", "Франция", "Россия" }; } @using BookStore.Helpers <h3>Города</h3> @Html.CreateList(cities) <br /> <h3>Страны</h3> <!-- или можно вызвать так --> @ListHelper.CreateList(Html, countries)
Ряд элементов html могут быть самозакрывающимися без парного закрывающего тега, например, элемент <img />
. Чтобы обозначить элемент как
самозакрывающийся, мы можем применить значение TagRenderMode.SelfClosing. К примеру, добавим в папку Helpers новый класс,
который назовем ImageHelper:
using System.Web.Mvc; public static class ImageHelper { public static MvcHtmlString Image(this HtmlHelper html, string src, string alt) { TagBuilder img = new TagBuilder("img"); img.MergeAttribute("src", src); img.MergeAttribute("alt", alt); return MvcHtmlString.Create(img.ToString(TagRenderMode.SelfClosing)); } }
Здесь метод Image()
также представляет собой метод расширения для класса HtmlHelper, и кроме того, он принимает еще два параметра - для атрибутов src
и alt
.
Для создания объекта MvcHtmlString здесь применяется статический метод MvcHtmlString.Create()
, в который также передается текстовое содержимое
TagBuilder. Но так как элемент img самозакрывающийся, здесь также применяется TagRenderMode.SelfClosing
.
Затем данный хелпер мы сможем также использовать в представлении, как и любой другой:
@using BookStore.Helpers @Html.Image("/Content/cats1.jpg", "спящий котэ")
Стандартные реализации хелперов позволяют добавить к создаваемым элементам атрибуты, например, атрибут class, id и другие. В кастомные хелперы мы также можем добавлять атрибуты. Например, изменим хелпер CreateList следующим образом:
using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Web.Mvc; public static class ListHelper { public static MvcHtmlString CreateList(this HtmlHelper html, string[] items, object htmlAttributes = null) { TagBuilder ul = new TagBuilder("ul"); foreach (string item in items) { TagBuilder li = new TagBuilder("li"); li.SetInnerText(item); ul.InnerHtml += li.ToString(); } ul.MergeAttributes(HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes)); return MvcHtmlString.Create(ul.ToString()); } }
Теперь в качестве второго параметра передается объект htmlAttributes, свойства которого должны представлять собой передаваемые в хелпер атрибуты.
С помощью метода HtmlHelper.AnonymousObjectToHtmlAttributes()
данный объект преобразуется в атрибуты html, которые затем добавляются к элементу.
И в этом случае в коде представления мы можем передать в хелпер значения для атрибутов:
@Html.CreateList(new string[] { "Лондон", "Париж", "Берлин" }, new { @class = "btn", id = "citiesList" })