HTML-хелперы

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

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

Как мы увидели из прошлых примеров, представления используют разметку 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#

Также для определения хелпера мы можем использовать стандартные классы на 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" })
Дополнительные материалы
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850