Создание tag-хелперов

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

Чтобы создать свой tag-хелпер, нам надо унаследовать класс от класса TagHelper, переопределив его метод Process или ProcessAsync().

Определение tag-хелпера

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

using Microsoft.AspNetCore.Razor.TagHelpers;

namespace MvcApp.TagHelpers
{
    public class TimerTagHelper : TagHelper
    {
        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
        }
    }
}
Создание tag-хелперов в ASP.NET Core MVC и C#

По умолчанию tag-хелперы применяют соглашения об наименовании, согласно которым класс должен оканчиваться на суффикс TagHelper. Хотя это не является обязательной практикой, мы могли бы определить и просто класс Timer:

public class Timer : TagHelper
{
}

А вся остальная часть названия, которая идет до TagHelper, будет использоваться в качестве названия тега, то есть <timer>.

Для генерации элемента html на основе тега используется метод Process. Он принимает два параметра: объект TagHelperContext, представляющий контекст тега (его содержимое, атрибуты), и объект TagHelperOutput, отвечающий за генерацию выходного элемента html на основе тега.

Теперь изменим определение класса следующим образом:

using Microsoft.AspNetCore.Razor.TagHelpers;
namespace MvcApp.TagHelpers
{
    public class TimerTagHelper : TagHelper
    {
        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            output.TagName = "div";    // заменяет тег <timer> тегом <div>
           // устанавливаем содержимое элемента
            output.Content.SetContent($"Текущее время: {DateTime.Now.ToString("HH:mm:ss")}");
        }
    }
}

Подключение tag-хелпера

Чтобы задействовать класс хелпера в представлении, нам надо подключить его функциональность в представление следующим образом:

@addTagHelper *, MvcApp

В данном случае предполагается, что проект приложения называется MvcApp. Для добавления хелпера используется директива addTagHelper. Директива использует синтаксис подстановочных знаков, определяя, какие tag-хелперы будут загружаться в представление. И также указывается сборка, которая содержит классы хелперы. То в директиве

@addTagHelper *, MvcApp

первая часть до запятой (в данном случае символ звездочка) указывает, какие tag-хелперы будут загружаться в представление (символ звездочки * используется для загрузки всех хелперов). А вторая часть после запятой указывает на сборку, в которой хранятся хелперы - в данном случае сборка MvcApp (так как хелперы определены в текущем проекте).

Если представления использует файл _ViewImports.cshtml, то данную директиву можно определить в _ViewImports.cshtml, чтобы подключить хелпер сразу во все представления.

Использование tag-хелпера

Теперь используем выше определенный tag-хелпер TimerTagHelper в каком-нибудь представлении:

@addTagHelper *, MvcApp

<timer></timer>

При этом не важно, что элемент <timer> пустой. Можно добавить в него какой-нибудь текст, но он не имеет значение. Главное, что этот тег называется по имени класса без суффикса TagHelper. И в итоге вместо этого тега будет сгенерирован элемент <div>, в котором будет выводиться время:

Создание и подключение tag helper в ASP.NET Core MVC и C#

Асинхронные операции в тег-хелпере

Если в tag-хелпер должен выполнять какие-то асинхронные операции, например, обращаться к базе данных или к файлу в асинхронном режиме, то вместо метода Process() мы можем переопределить другой метод класса TagHelper - метод ProcessAsync(). Например:

using Microsoft.AspNetCore.Razor.TagHelpers;

namespace MvcApp.TagHelpers
{
    public class TimerTagHelper : TagHelper
    {
        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            output.TagName = "div";
            output.Content.SetContent($"Текущее время: {DateTime.Now.ToString("HH:mm:ss")}");
        }
    }
    public class DateTagHelper : TagHelper
    {
        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            output.TagName = "div";
            output.Content.SetContent($"Текущая дата: {DateTime.Now.ToString("dd/mm/yyyy")}");
        }
    }
    public class SummaryTagHelper : TagHelper
    {
        public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
        {
            output.TagName = "div";
            // получаем вложенный контекст из дочерних tag-хелперов
            var target = await output.GetChildContentAsync();
            var content = "<h3>Общая информация</h3>" + target.GetContent();
            output.Content.SetHtmlContent(content);
        }
    }
}

Здесь определены три tag-хелпера. TimerTagHelper и DateTagHelper однотипны, выводят время и дату соответственно. SummaryTagHelper служит как-бы оберткой для обоих хелперов. Предполагается, что TimerTagHelper и DateTagHelper будут вложены в SummaryTagHelper. Например, следующим образом:

@addTagHelper *, MvcApp

<summary>
    <timer></timer>
    <date></date>
</summary>
Асинхронный tag-хелпер в ASP.NET Core MVC и C#

В SummaryTagHelper вызывает асинхронный метод output.GetChildContentAsync(), который возвращает сгенерированную разметку html для вложенных tag-хелперов. Затем мы можем дополнительно каким-либо образом изменить эту разметку и установить ее в качестве содержимого.

И этот как раз тот случай, когда можно использовать асинхронный метод ProcessAsync.

Если tag-хелпер содержит оба метода: и Process(), и ProcessAsync(), то вызываться будет именно метод ProcessAsync().

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850