Введение в Тэг-хелперы (Tag Helpers)

Rick Anderson

Что такое Tag Helpers?

Tag Helpers заставляют код со стороны сервера участвовать в создании и представлении HTML элементов в Razor файлах. Например, встроенный ImageTagHelper может присоединить номер версии к имени изображения. Когда изображение меняется, сервер генерирует новую уникальную версию изображения, так что клиент гарантированно получит текущую версию изображения (вместо кэшированного изображения). Для общих целей существует много встроенных Tag Helpers - например, для создания форм, ссылок, загрузки и тд - и многие из них доступны в открытых GitHub репозиториях и в качестве NuGet пакетов. Tag Helpers работают с HTML элементами, основываясь на имени элемента, имени атрибута или родительском тэге. Например, встроенный LabelTagHelper может работать с HTML элементом <label>, если применяются атрибуты LabelTagHelper. Если вы знакомы со вспомогательными методами HTML, то поймете, что Tag Helpers уменьшают явные переходы между HTML и C# в Razor представлениях. См. Tag Helpers по сравнению со вспомогательными методами HTML.

Чем полезны Tag Helpers

Большая схожесть с HTML
По большей части разметка Razor, где используются Tag Helpers, выглядит, как стандартный HTML. Фронтэнд разработчики, работающие с HTML/CSS/JavaScript, могут редактировать Razor без необходимости изучать синтаксис C# Razor.
Поддержка IntelliSense при создании HTML и Razor разметки
В этом Tag Helpers сильно отличаются от вспомогательных методов HTML. В разделе Tag Helpers по сравнению со вспомогательными методами HTML более подробно объясняется эта разница. Кроме того, вам стоит уделить особое внимание разделу Поддержка IntelliSense для Tag Helpers. Даже разработчики, сведущие в синтаксисе Razor C#, работают более продуктивно, используя Tag Helpers, нежели создавая C# Razor разметку.
Вы сможете работать более продуктивно и создавать более надежный, устойчивый и безопасный код, используя информацию, которая доступна только на сервере
Например, когда ранее мы хотели изменить изображение, нам нужно было изменить название изображения. Изображения нужно было обязательно кэшировать по причинам эффективности, и пока мы не меняли имя изображения, клиенты могли получать его копию. Исторически после редактирования изображения нужно было обязательно менять его имя и каждую ссылку на него в веб приложении. Мало того, что это трудоемкий процесс, так еще у вас могут возникнуть и ошибки (вы можете пропустить ссылку, случайно ввести неправильную строку и тд.) Встроенный ImageTagHelper может сделать это автоматически. ImageTagHelper присоединяет номер версии к имени изображения, так что когда изображение меняется, сервер автоматически генерирует новую уникальную версию изображения. Клиенты гарантированно получают текущее изображение. Все это достигается с помощью ImageTagHelper.

Большинство встроенных Tag Helpers нацелены на существующие HTML элементы и предоставляют для элемента атрибуты на стороне клиента. Например, элемент <input>, использующийся во многих представлениях в папке Views/Account, содержит атрибут asp-for, который извлекает имя имя указанного свойства модели в представленный HTML. Следующая разметка Razor:

<label asp-for="Email"></label>

генерирует следующий HTML:

<label for="Email">Email</label>

Атрибут asp-for доступен для свойства For в LabelTagHelper. См. Создание элементов Tag Helper.

Управление Tag Helpers

Tag Helpers контролируются комбинацией @addTagHelper, @removeTagHelper и знаком ”!” opt-out.

@addTagHelper делает Tag Helpers доступными

Если вы создаете новое ASP.NET Core приложение с именем AuthoringTagHelpers (без аутентификации), в ваш проект будет добавлен следующий файл Views/_ViewImports.cshtml:

@using AuthoringTagHelpers
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

Директива @addTagHelper делает Tag Helpers доступными для представления. В данном случае файлом представления является Views/_ViewImports.cshtml, который по умолчанию наследуется всеми файлами представлений в папке Views и подпапками; таким образом, Tag Helpers становятся доступными для всех. В коде сверху используется синтаксис “*” для указания того, что все Tag Helpers в указанной сборке (Microsoft.AspNet.Mvc.TagHelpers) будут доступны для каждого файла представления в директории Views или поддиректории. Первый параметр после @addTagHelper говорит, что Tag Helpers надо загрузить (мы используем “*” для всех Tag Helpers), а второй параметр “Microsoft.AspNet.Mvc.TagHelpers” указывает сборку, содержащую Tag Helpers. Microsoft.AspNet.Mvc.TagHelpers - это сборка для встроенных Tag Helpers.

Чтобы использовать все Tag Helpers в данном проекте (где создается сборка AuthoringTagHelpers), мы сделаем следующее:

@using AuthoringTagHelpers
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper "*, AuthoringTagHelpers"

Если в вашем проекте содержится EmailTagHelper с пространством имен по умолчанию (AuthoringTagHelpers.TagHelpers.EmailTagHelper), вы можете использовать полное имя (FQN) элемента Tag Helper:

@using AuthoringTagHelpers
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper "AuthoringTagHelpers.TagHelpers3.EmailTagHelper, AuthoringTagHelpers"

Чтобы добавить Tag Helper в представление с помощью FQN, вы сперва добавляете FQN (AuthoringTagHelpers.TagHelpers.EmailTagHelper), а затем имя сборки (AuthoringTagHelpers). Большинство разработчиков предпочитают использовать синтаксис wildcard - “*”. Синтаксис wildcard позволяет вставлять символы wildcard “*” в качестве суффикса в FQN. Например, некоторые из следующих директив добавят EmailTagHelper:

@addTagHelper "AuthoringTagHelpers.TagHelpers.E*, AuthoringTagHelpers"
@addTagHelper "AuthoringTagHelpers.TagHelpers.Email*, AuthoringTagHelpers"

Как упоминалось ранее, добавление директивы @addTagHelper в файл Views/_ViewImports.cshtml делает элемент Tag Helper доступным для всех файлов представлений в директории Views и поддиректориях. Вы можете использовать директиву @addTagHelper в конкретных файлах представлений, если вы хотите, чтобы элемент Tag Helper находился только в этих представлениях.

@removeTagHelper удаляет Tag Helpers

У @removeTagHelper есть те же два параметра, что и у @addTagHelper, и эта директива удаляет ранее добавленный элемент Tag Helper. Например, если применить @removeTagHelper к конкретному представлению, то она удалит из этого представления конкретный Tag Helper. Использование @removeTagHelper в файле Views/Folder/_ViewImports.cshtml удаляет определенный элемент Tag Helper со всех представлений в папке.

Контроль над элементами Tag Helper с помощью файла _ViewImports.cshtml

Вы можете добавить _ViewImports.cshtml в любую папку представления, и движок представления добавит директивы из файла _ViewImports.cshtml к тем, что содержатся в файле Views/_ViewImports.cshtml. Если вы добавили пустой файл Views/Home/_ViewImports.cshtml для представлений Home, ничего не изменится, поскольку файл _ViewImports.cshtml является дополнительным. Любая директива @addTagHelper, которую вы добавляете в файл Views/Home/_ViewImports.cshtml (и которая не находится по умолчанию в файле Views/_ViewImports.cshtml) вызовет Tag Helpers только в папке Home.

Удаление отдельных элементов

Вы можете отключить Tag Helper на уровне элемента с помощью символа opt-out (”!”). Например, валидация Email отключена в <span> с помощью данного символа:

<!span asp-validation-for="Email" class="text-danger"></!span>

Вы должны применять символ opt-out в открывающем и закрывающем тэгах. (Редактор Visual Studio автоматически добавляет символ opt-out в закрывающий тэг, если вы добавили такой в открывающий тэг). После добавления символа opt-out атрибуты элемента и Tag Helper больше не будут отображаться с помощью определенного шрифта.

Использование @tagHelperPrefix для явного использования Tag Helper

Директива @tagHelperPrefix позволяет вам указать строку префикса тэга, чтобы включить поддержку Tag Helper и использовать Tag Helper напрямую. На рисунке внизу префикс Tag Helper установлен на “th:”, так что только элементы, где используется префикс “th:”, поддерживают Tag Helpers. У элементов <label> и <span> есть префикс Tag Helper, а у элемента <input> его нет.

../../../_images/thp.png

Правила иерархии, которые применяются к @addTagHelper, также применяются и к @tagHelperPrefix.

Поддержка IntelliSense для Tag Helpers

Когда вы создаете новое ASP.NET приложение в Visual Studio, то в файл project.json добавляется “Microsoft.AspNet.Tooling.Razor”. Этот пакет добавляет инструментарий Tag Helper.

Пропишите HTML элемент <label>. Когда вы введете в редакторе Visual Studio <l, IntelliSense отобразит подходящие элементы:

../../../_images/label.png

Вы получаете не только HTML помощь, но и видите иконку (символ “@” с “<>” под ним).

../../../_images/tagSym.png

Она показывает элемент, на который нацелены Tag Helpers. Чистые HTML элементы (например, fieldset) отображают иконку “<>”.

Чистый HTML тэг <label> отображается (с помощью базовой цветовой гаммы Visual Studio) коричневым цветом, атрибуты - красным, а значения атрибутов - синим.

../../../_images/LableHtmlTag.png

После того как вы введете <label, IntelliSense просмотрит все HTML/CSS атрибуты и Tag Helper-атрибуты:

../../../_images/labelattr.png

IntelliSense позволяет вам заполнить выражение выбранным значением:

../../../_images/stmtcomplete.png

После введения атрибута Tag Helper, шрифты тэга и атрибута поменяются. При использовании базовых цветовых схем Visual Studio “Blue” или “Light” цвет будет пурпурным. Если вы используете схему “Dark”, цвет будет насыщенно бирюзовым. Здесь мы использовали схему по умолчанию.

../../../_images/labelaspfor2.png

Вы можете использовать горячие клавиши Visual Studio CompleteWord (Ctrl + пробел по умолчанию) внутри двойных кавычек (“”), и теперь вы в C#. IntelliSense отображает все методы и свойства модели страницы. Методы и свойства доступны, поскольку типом свойства является ModelExpression. На рисунке снизу я редактирую представление Register, так что нам доступен RegisterViewModel.

../../../_images/intellemail.png

IntelliSense просматривает свойства и методы, доступные для модели. IntelliSense помогает вам выбрать CSS класс:

../../../_images/iclass.png ../../../_images/intel3.png

Tag Helpers по сравнению со вспомогательными методами HTML

Tag Helpers присоединяются к HTML элементам в Razor представлениях, тогда как вспомогательные методы HTML вызываются с HTML в Razor представлениях. Представьте себе следующую маркировку Razor, которая создает HTML label с CSS классом “caption”:

@Html.Label("FirstName", "First Name:", new {@class="caption"})

Символ “at” (@) говорит Razor, что это начало кода. Следующие два параметра (“FirstName” и “First Name:”) являются строками, так что IntelliSense помочь здесь не может. Последний аргумент:

new {@class="caption"}

является анонимным объектом, который используется для представления атрибутов. Поскольку class является зарезервированным ключевым словом в C#, мы используем символ @, чтобы заставить C# интерпретировать “@class=” как символ (имя свойства). Для фронтэнд разработчика (того, кто знаком с HTML/CSS/JavaScript и другими клиентскими технологиями, но не знаком с C# и Razor), большая часть этой строки непонятна. И вся строка должны быть написана без помощи IntelliSense.

С помощью LabelTagHelper та же разметка может быть написана вот так:

../../../_images/label2.png

При использовании Tag Helper как только вы вводите <l в редакторе Visual Studio, IntelliSense отобразит соответствующие элементы:

../../../_images/label.png

IntelliSense помогает вам все прописать. LabelTagHelper также устанавливает контент значения атрибута asp-for (“FirstName”) на “First Name”; он конвертирует CamelCase свойства в выражения, состоящие из имени свойства с пробелом, где все пишется с большой буквы. При следующей разметке:

../../../_images/label2.png

генерирует:

<label class="caption" for="FirstName">First Name</label>

Такой прием не используется, если вы добавляете контент в <label>. Например:

../../../_images/1stName.png

генерирует:

<label class="caption" for="FirstName">Name First</label>

В следующем коде показана часть Form представления Views/Account/Register.cshtml Razor, сгенерированного из шаблона ASP.NET 4.5.x MVC, включенного в Visual Studio.

../../../_images/regCS.png

Редактор Visual Studio отображает C# на сером заднем фоне. Например, вспомогательный метод HTML AntiForgeryToken:

@Html.AntiForgeryToken()

отображается на сером заднем фоне. Большинство разметки в представлении Register является C# кодом. Сравните это с эквивалентом, где используются Tag Helpers:

../../../_images/regTH.png

Разметка здесь более чистая, ее проще читать, редактировать и поддерживать. Количество C# кода уменьшено до минимума - здесь есть только то, что необходимо знать серверу. Редактор Visual Studio отображает разметку, на которую нацелен Tag Helper, характерным шрифтом.

Обратите внимание на Email группу:

У каждого из атрибутов “asp-” есть значение “Email”, но “Email” не является строкой. В данном контексте “Email” - это свойство модельного выражения C# для RegisterViewModel.

Редактор Visual Studio помогает вам прописать всю разметку, если вы используете элементы Tag Helper, а если вы используете вспомогательные методы HTML, то помощи от Visual Studio вы почти не получите. Больше информации вы можете получить в разделе Поддержка IntelliSense для Tag Helpers.

Tag Helpers по сравнению с Web Server Controls

  • Tag Helpers не принадлежат элементу, с которым они связаны; они просто участвуют в отображении элемента и контента. ASP.NET Web Server controls объявляются и вызываются на странице.
  • У Web Server controls нестандартный жизненный цикл, что усложняет разработку и отладку.
  • Web Server controls позволяют добавлять функционал в элементы DOM. Tag Helpers этого не могут.
  • Web Server controls включают в себя автоматическое обнаружение браузера. Tag Helpers ничего не знают о браузере.
  • Несколько Tag Helpers могут работать с одним и тем же элементом (см. Как избежать конфликта Tag Helper), а Web Server controls скомбинировать нельзя.
  • Tag Helpers могут менять тэг и контекст HTML элементов, с которыми они связаны, но напрямую они не влияют больше ни на что на странице. Web Server controls могут выполнять действия, которые влияют на другие части страницы, и это иногда может привести к побочным эффектам.
  • Web Server controls конвертируют строки в объекты. С Tag Helpers вы работаете изначально в C#, так что конвертация вам не нужна.
  • Web Server controls используют System.ComponentModel, чтобы реализовать поведение компонентов во время разработки и при рантайме. System.ComponentModel включает в себя базовые классы и интерфейсы для реализации атрибутов и конвертации типов, связывая источники данных и компоненты. Tag Helpers наследуются от TagHelper, и базовый класс TagHelper предлагает только два метода - Process и ProcessAsync.

Настройка шрифта элемента Tag Helper

Вы можете настроить шрифт и цвет из Tools > Options > Environment > Fonts and Colors:

../../../_images/fontoptions2.png
Поделись хорошей новостью с друзьями!
Следи за новостями!