Размер шрифта:
Полное руководство по использованию Core 1. 0 (aka 5) Tag Helpers / Хабр

Полное руководство по использованию Core 1. 0 (aka 5) Tag Helpers / Хабр

Полное руководство по использованию ASP.NET Core 1.0 (aka ASP.NET 5) Tag Helpers

Тег-хэлперы (Tag Helpers) – новая функция MVC, которую удобно использовать для генерации HTML кода. Они выглядят как обычные HTML элементы и атрибуты, но обрабатываются движком Razor на стороне сервера. Тег-хэлперы во многом представляют собой альтернативный синтаксис для HTML Helpers, но также они позволяют сделать то, что было трудно или невозможно сделать с помощью HTML Helpers. У каждого тег-хэлпера свое поведение и возможности. Эта статья рассмотрит базовые тег-хэлперы, существующие в MVC 6 (ASP .NET Core 1.0, как стало известно совсем недавно).

Добавление тег-хэлперов для использования в представлении

Если вы создаете новый MVC 6 проект с помощью Visual Studio, то встроенные тег-хэлперы будут доступны по умолчанию. Можно добавить тег-хэлперы из любой сборки / пространства имен, используя директиву @addTagHelper в cshtml файлах.

Чтобы добавить тег-хэлперы глобально для всего проекта, добавьте директиву @addTagHelper в файл Views/_ViewImports.cshtml.

Link и Script

Как видно из их названий, эти тег-хэлперы созданы для упрощения добавления тегов link и script в создаваемую HTML разметку. Например, с их помощью можно упростить добавление ссылок на большое число файлов в девелопмент среде, использование CDN с откатом на локальные файлы и инвалидацию кеша. Рассмотрим пример, в котором мы хотим добавить ссылки на все js файлы в определенной папке (рисунок 1).

Мы можем это легко сделать с помощью тег-хэлпера Script, добавив все файлы по шаблону:

В результате будет сгенерирована следующая HTML разметка:

В данном примере мы использовали шаблон /app/**/*.js, потому что нам нужно было включить еще и js файлы из подпапок. Если же мы хотим добавить ссылки на все js файлы из одной папки, то используем шаблон /app/*.js. Наряду с атрибутом asp-src-include существует и атрибут asp-src-exclude. Например, в предыдущем примере мы можем сделать так, чтобы ссылки на js файлы в подпапке services не были добавлены:

Тег-хэлпер Link работает точно так же, только с атрибутами asp-href-include и asp-href-exclude. Теперь рассмотрим атрибуты этих тег-хэлперов, которые помогут подключать CDN. Преимущества использования CDN для хостинга файлов таких популярных фреймворков как jQuery и Bootstrap очевидны: уменьшается нагрузка на наши сервера и потенциально увеличивается производительность у клиента (например, актуальная версия файла уже может быть в кеше браузера у клиента). Среди минусов – нужно предусмотреть возможность того, что CDN не отвечает и нам нужно отдавать файлы со своего сервера. С помощью тег-хэлперов это сделать проще:

Атрибуты asp-fallback-test позволяют указать свойства или объекты, которые нужно проверить для того, чтобы узнать, был ли загружен файл или нет. Если нет, то файл будет загружен с использованием пути, заданном в атрибуте asp-fallback-href. Сгенерированная HTML разметка:

Cache busting (инвалидация кеша) – механизм, добавляющий идентификатор версии файла (на основе его содержимого) к имени файла для css и js файлов. В этом случае можно указать браузеру, что эти файлы можно кешировать на неопределенно долгое время, в случае их изменения имя у них также изменится. Для того чтобы включить этот механизм, достаточно добавить атрибут asp-append-version:

Environment

Тег-хэлпер Environment используется (обычно вместе с тег-хэлперами Link и Script) для генерирования различной HTML разметки в зависимости от среды: девелопмент vs тест vs продакшен. Этот тег-хэлпер используется следующим образом: оберните в этот тег часть HTML кода и укажите среду или среды, для которых эта часть разметки должна быть включена в выходной файл. В следующем примере в девелопмент среде мы подключаем все css файлы по отдельности, а в средах Staging и Production используем скомбинированную минифицированную версию.

В девелопмент среде будет сгенерирован следующий HTML код:

В средах Staging и Production будет добавлена ссылка на минифицированную версию:

Сам тег environment не посылается клиенту. Его значение задается переменной Hosting:Environment. В ASP.NET Core 1.0 (MVC 6) Hosting:Environment используется для тех же целей, для каких раньше использовалась Debug / Release конфигурация. Обычно Hosting:Environment принимает значения: Development, Staging и Production. Значением по умолчанию при запуске сайта из Visual Studio является Development. В этом можно убедиться, открыв свойства MVC проекта в Visual Studio (рисунок 2).

  • Кликнуть правой кнопкой мыши по проекту в обозревателе решений и выбрать Свойства.
  • Выбрать вкладку Debug (Отладка).
  • Нажмите New… для создания нового профиля и назовите его “IIS Express – Prod”.
  • В выпадающем списке Launch выберите “IIS Express”.
  • Добавьте новую переменную окружения с именем “Hosting:Environment” и значением “Production”.
  • Сохраните проект.

Теперь в выпадающем списке Run в Visual Studio можно выбрать профиль “IIS Express – Prod” (рисунок 4).

Именно в этом разделе тег-хэлперы делают свою работу лучше всего, увеличивая читаемость и простоту cshtml представлений. В качестве примера рассмотрим простую логин форму со следующей моделью:

Теперь посмотрим, как можно сгенерировать поле ввода для свойства UserName.

Когда мы используем HTML хэлпер, то вызываем обычный C# метод, который возвращает некоторую HTML разметку. С тег-хэлперами мы имеем дело сразу с обычной HTML разметкой, в которой встречаются MVC специфичные атрибуты. В результате обоих подходов на выходе мы получим один и тот же сгенерированный HTML код:

Почему подход с тег-хэлперами лучше? Код с ними становится читаемее и проще. Например, мы хотим добавить к полю ввода класс:

В данном случае код с использованием тег-хэлперов однозначно выигрывает и в красоте, и в простоте. Теперь приведем код всей формы логина в двух вариантах.

Как мы видим, версия с тег-хэлперами выглядит проще и читаемее. Особенно мне нравится отсутствие выражения using для генерации формы, мне всегда это казалось каким-то хаком. Еще стоит отметить, что нам теперь не нужно явно добавлять AntiForgeryToken на форму. Тег-хэлпер form делает это автоматически, если не отключить это поведение атрибутом asp-anti-forgery=”false”. Конечно, Visual Studio подсвечивает атрибуты тег-хэлперы, чтобы их легко можно было отличить от стандартных HTML атрибутов (рисунок 5):

Внутри атрибутов asp-for работает IntelliSense, подсказывающий имена свойств модели (рисунок 6).

Теперь рассмотрим атрибуты тег-хэлпера form. Например для того, чтобы связать форму с определенным действием определенного контроллера, используются атрибуты asp-controller и asp-action:

В результате будет сгенерирована следующая HTML разметка:

Как мы видим, по умолчанию добавляется AntiForgeryKey, а методу формы присваивается значение POST. Это поведение можно изменить, добавив в разметку переопределение атрибута method. Все HTML атрибуты, добавленные в разметку, попадут в сгенерированный код. Однако стоит учесть, что нельзя одновременно задать атрибут action и один из атрибутов asp-controller / asp-action, в этом случае будет выброшено исключение: «Cannot override the ‘action’ attribute for . A with a specified ‘action’ must not have attributes starting with ‘asp-route-‘ or an ‘asp-action’ or ‘asp-controller’ attribute.» Иногда действию контроллера нужно передать дополнительные параметры. Это можно сделать с помощью атрибутов, начинающихся с asp-route-. Например, в действие Login часто передается параметр ReturnUrl, вот как это можно сделать с использованием тег-хэлперов:

В итоге будет сгенерирован такой HTML код:

Используя такой синтаксис, можно указывать столько параметров, сколько необходимо. Еще тег-хэлпер form поддерживает возможность указать именованный маршрут вместо пары контроллер / действие. Предположим, что мы определили маршрут с именем login в MVC коде:

Тогда мы можем указать этот маршрут для формы, используя атрибут asp-route:

Что в свою очередь сгенерирует точно такую же HTML разметку, как и в предыдущем случае:

Input

Тег-хэлпер input является альтернативой Html.EditorFor. В следующем примере будем использовать такой простой класс модели представления:

Поле ввода для Email можно создать с помощью asp-for атрибута:

В результате чего получим следующую HTML разметку:

Тег-хэлпер добавляет атрибуты id и name, значение которых задается именем свойства, указанным в asp-for. Тип сгенерированного input был установлен в text потому, что тип свойства Email string. Если бы тип свойства был bool, то тег-хэлпер сгенерировал бы input с типом checkbox. Ниже представлена таблица соответствия .NET типов и HTML input типов. .NET тип HTML input тип String type=”text” DateTime type=”datetime” Byte type=”number” Int16, Int32, Int64 type=”number” Single, Double type=”number” Boolean type=”checkbox” Тег-хэлпер input принимает во внимание не только тип свойства, но и валидационные атрибуты. Например, добавим [Required] к свойству Email:

В этом случае в сгенерированной HTML разметке будет атрибут data-val-required, который используется jQuery Validation.

Если добавить атрибут [EmailAddress] к свойству модели, то будет сгенерирован input с типом email и атрибутом data-val-email. Ниже приведена таблица с указанием .NET атрибутов, которые соответствуют различным типам HTML input. Атрибут HTML input тип [EmailAddress] type=”email” [Url] type=”url” [HiddenInput] type=”hidden” [DataType(DataType.Password)] type=”password” [DataType(DataType.Date)] type=”date” [DataType(DataType.Time)] type=”time” Также можно использовать дочерние объекты в моделях представления. Чуть усложним нашу модель.

В представлении мы можем создать поле ввода для Address.AddressLine1:

В результате получим следующий HTML код:

Конечно, все атрибуты, которые будут в cshtml файле применены тег-хэлперу input, будут добавлены в сгенерированную HTML разметку. Еще одной возможностью, предоставляемой тег-хэлпером input, является использование обычной <a href=” msdn.microsoft.com/en-us/library/dwhawy9k.aspx”>строки форматирования, широко использующейся в .NET. Для этого используется атрибут asp-format, например:

В этом случае число будет показано с 4 знаками после запятой, например, 1.2000. Никаких дополнительных атрибутов не добавляется. Как мы уже говорили, Visual Studio предоставляет IntelliSense для тег-хэлпера input, подсвечивает ошибки, если есть ошибка в имени свойства. Исключение в таком случае будет выброшено во время компиляции, но по умолчанию Razor представления не прекомпилируются, поэтому эта ошибка будет видна только при первом обращении к странице.

TextArea

Тег-хэлпер textarea во многом похож на ранее рассмотренный input и является альтернативой Html.TextAreaFor. Он также использует атрибут asp-for. Рассмотрим следующую модель представления:

Мы используем тег-хэлпер textarea следующим образом:

Что сгенерирует следующую HTML разметку:

В сгенерированном элементе textarea определены name, id, добавлены валидационные атрибуты.

Validation

Мы увидели, что добавлять валидационные атрибуты несложно, теперь обсудим, где показывать валидационные сообщения. Раньше для этого использовался метод Html.ValidationMessageFor, теперь – атрибут asp-validation-for, применяемый к элементу span.

Это сгенерирует следующую HTML разметку, в случае если поле Email было сделано обязательным, но не было заполнено:

  • ValidationSummary.All – будут показаны и сообщения уровня всей модели, и сообщения для всех ее свойств.
  • ValidationSummary.ModelOnly – будут показаны только сообщения уровня всей модели
  • ValidationSummary.None – тег-хэлпер ничего не делает, как если бы вы не добавляли атрибут asp-validation-summary. Единственным применением видится быстрое отключение всех валидационных сообщений для каких-то своих девелоперских нужд.

Этот код сгенерирует следующую разметку в случае, когда валидационных ошибок нет:

Если же у нас есть ошибки валидации:

Label

Тег-хэлпер label является самым скучным простым тег-хэлпером, заменой Html.LabelFor. Его единственная задача – сгенерировать элемент label для поля, имя которого указано в атрибуте asp-for. Значение для содержимого этого label задается свойством Name атрибута Description. Рассмотрим такую модель представления:

Теперь используем тег-хэлпер label:

Что в результате даст нам следующую HTML разметку:

Select

Тег-хэлпер select используется для создания выпадающих списков в HTML разметке вместо Html.DropDownListFor. Пусть у нас есть модель со свойством CountryCode, которое мы хотим заполнять с помощью выпадающего списка:

Теперь с помощью тег-хэлпера свяжем это поле с элементом select.

И получим следующий HTML код:

Конечно, этот код не несет практической ценности, потому что выпадающий список еще пуст. Есть 2 способа его заполнить. Первый (для совсем маленьких списков): все возможные варианты задать вручную в представлении:

В этом случае значение будет выбрано исходя из значения свойства в модели. Например, если CountryCode равен “CA”, будет сгенерирована следующая HTML разметка:

Второй способ задания возможных значений – динамическая загрузка из источника данных. Для этого нужен источник данных типа IEnumerable<SelectListItem> (или SelectList), пусть в нашем случае он доступен в ViewBag.Countries. Для привязки источника данных используется атрибут asp-items:

Для того, чтобы сгенерированный элемент select поддерживать возможность выбора нескольких элементов, достаточно, чтобы свойство модели имело тип IEnumerable, например:

В коде использования тег-хэлпера ничего не меняем:

Но сгенерированная HTML разметка будет другой:

Anchor

Тег-хэлпер anchor служит для генерации ссылок и является заменой как Html.ActionLink, так и Url.Action, с помощью которых мы обычно писали вот так:

И в результате получали две одинаковые ссылки:

Теперь с помощью тег-хэлпера anchor и атрибутов asp-controller, asp-action ссылку можно добавить следующим образом:

Как и в случае остальных тег-хэлперов, их использование позволяет проще добавить дополнительные классы и атрибуты для этих элементов, в отличие от Html.ActionLink(«Register », «Create», “Account”, null, new < class= «css-class»> ). Если в метод контроллера надо передать дополнительные параметры, то это можно сделать так же, как и для тег-хэлпера form: с помощью атрибутов asp-route-*, например:

Также можно указать именованный маршрут (опять точно так же, как для form):

Ранее используемый Html.ActionLink позволял указать протокол, хост и фрагмент генерируемого URL. У тег-хэлпера есть для этого свои атрибуты:

Cache

У тег-хэлпера cache нет аналога среди Html хэлперов, да и обычным HTML элементом он не является. Он позволяет закешировать свое содержимое в памяти. Перед каждой обработкой своего содержимого он проверяет, не было ли оно уже сохранено в MemoryCache. Если содержимое найдено в кеше, оно отправляется сразу в Razor движок, если нет – сначала Razor обработает его, а потом оно сохранится в кеш. По умолчанию тег-хэлпер сгенерирует уникальный ID своего содержимого. Вот так его можно использовать в представлениях:

    expires-after: задает промежуток времени от текущего момента, во время которого кеш считается валидным, например, 5 секунд. Атрибут expires-after ожидает объект типа TimeSpan:

Ограничения этого тег-хэлпера связаны с тем, что он использует MemoryCache в свое реализации. Первое ограничение связано с тем, что любой перезапуск процесса, ресайкл пула приложения и похожее действие инвалидирует весь наш кеш, в облаке такое может произойти, если сайт переедет на новую машину. Поэтому нельзя считать этот кеш надежным. Второе ограничение также связано с тем, что кеш хранится в памяти. Если пользователь в рамках сессии будет перенаправлен на разные веб-сервера, потенциально он может увидеть разное содержимое одного и того же элемента. Это связано с тем, что у каждого сервера будет своя версия кеша, реализация MemoryCache не является распределенной. В данном случае может помочь привязка пользователя к одному и тому же серверу (sticky session, server affinity).

Image

Этот простой в использовании тег-хэлпер состоит из всего одного атрибута asp-append-version, добавляемого к тегу img. Если передать этому атрибуту значение true, то к URL изображения будет добавлена строка, зависящая от содержимого картинки (как и в случае css / js файлов), что позволит браузеру кешировать ее неопределенно долгое время.

В результате будет сгенерирована похожая HTML разметка:

Использование этого тег-хэлпера упрощает выбор политики кеширования изображений сайта: при маленьком времени кеширования нивелируется выгода от его применения, при большом – потенциально при обновлении изображения клиент в течение долгого времени продолжает использовать старую локально закешированную версию изображения.

📎📎📎📎📎📎📎📎📎📎