Вспомогательные компоненты тегов в ASP.NET Core
Авторы: Скотт Адди (Scott Addie) и Хасан Фияз Бин (Hasan Fiyaz Bin)
Вспомогательный компонент тегов позволяет на основе условий изменять или добавлять элементы HTML из серверного кода. Эта функция доступна в ASP.NET Core 2.0 и более поздних версий.
ASP.NET Core включает в себя два встроенных вспомогательных компонента тегов: head
и body
. Они находятся в пространстве имен и могут использоваться как Microsoft.AspNetCore.Mvc.Razor.TagHelpers в MVC, так и Razor в страницах. Компоненты вспомогательного тега не требуют регистрации в приложении _ViewImports.cshtml
.
Просмотреть или скачать образец кода (описание загрузки)
Случаи использования
Два распространенных варианта для использования вспомогательных компонентов тегов:
Эти варианты использования описаны в следующих разделах.
Внедрение в элемент HTML "head"
Внутри элемента HTML <head>
файлы CSS обычно импортируются с помощью элемента HTML <link>
. Следующий код позволяет вставить элемент <link>
в элемент <head>
с помощью вспомогательного компонента тегов head
:
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.TagHelpers;
namespace RazorPagesSample.TagHelpers
{
public class AddressStyleTagHelperComponent : TagHelperComponent
{
private readonly string _style =
@"<link rel=""stylesheet"" href=""/css/address.css"" />";
public override int Order => 1;
public override Task ProcessAsync(TagHelperContext context,
TagHelperOutput output)
{
if (string.Equals(context.TagName, "head",
StringComparison.OrdinalIgnoreCase))
{
output.PostContent.AppendHtml(_style);
}
return Task.CompletedTask;
}
}
}
В предыдущем коде:
AddressStyleTagHelperComponent
реализует TagHelperComponent. Абстракция:- Позволяет инициализировать класс с TagHelperContext.
- Позволяет использовать вспомогательные компоненты тегов для добавления или изменения элементов HTML.
- Свойство Order определяет порядок отображения компонентов. Свойство
Order
необходимо, если вспомогательные компоненты тегов используются в приложении несколько раз. - ProcessAsync сравнивает свойство TagName контекста выполнения со значением
head
. Если сравнение возвращает результат TRUE, содержимое поля_style
внедряется в элемент HTML<head>
.
Внедрение в элемент HTML "body"
Вспомогательный компонент тэгов body
позволяет внедрять элемент <script>
в элемент <body>
. Этот метод демонстрируется в приведенном ниже коде.
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.TagHelpers;
namespace RazorPagesSample.TagHelpers
{
public class AddressScriptTagHelperComponent : TagHelperComponent
{
public override int Order => 2;
public override async Task ProcessAsync(TagHelperContext context,
TagHelperOutput output)
{
if (string.Equals(context.TagName, "body",
StringComparison.OrdinalIgnoreCase))
{
var script = await File.ReadAllTextAsync(
"TagHelpers/Templates/AddressToolTipScript.html");
output.PostContent.AppendHtml(script);
}
}
}
}
Для хранения элемента <script>
используется отдельный HTML-файл. Этот HTML-файл делает код более чистым и удобным в обслуживании. Приведенный выше код считывает содержимое TagHelpers/Templates/AddressToolTipScript.html
и добавляет его с помощью выходных данных тега. Файл AddressToolTipScript.html
содержит следующую разметку:
<script>
$("address[printable]").hover(function() {
$(this).attr({
"data-toggle": "tooltip",
"data-placement": "right",
"title": "Home of Microsoft!"
});
});
</script>
Приведенный выше код привязывает мини-приложение подсказки начальной загрузки к любому элементу <address>
, который содержит атрибут printable
. Результат можно проследить при наведении указателя мыши на соответствующий элемент.
Регистрация компонента
Вспомогательные компоненты тегов необходимо добавить в коллекцию вспомогательных компонентов тегов приложения. Добавить его в коллекцию можно тремя способами:
- регистрация с помощью контейнера служб;
- Регистрация с помощью Razor файла
- регистрация с помощью модели страницы или контроллера.
Регистрация с помощью контейнера служб
Если ITagHelperComponentManager не управляет классом вспомогательного компонента тегов, класс нужно зарегистрировать в системе внедрения зависимостей (DI). Следующий код Startup.ConfigureServices
позволяет зарегистрировать классы AddressStyleTagHelperComponent
и AddressScriptTagHelperComponent
с ограниченным временем существования:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddTransient<ITagHelperComponent,
AddressScriptTagHelperComponent>();
services.AddTransient<ITagHelperComponent,
AddressStyleTagHelperComponent>();
}
Регистрация с помощью Razor файла
Если компонент вспомогательной функции тега не зарегистрирован в di, его можно зарегистрировать на Razor странице страницы или в представлении MVC. Этот метод используется для управления внедренной разметкой и порядка выполнения компонента из Razor файла.
ITagHelperComponentManager
позволяет добавлять вспомогательные компоненты тегов и (или) удалять их из приложения. Этот метод демонстрируется в следующем коде на примере AddressTagHelperComponent
:
@using RazorPagesSample.TagHelpers;
@using Microsoft.AspNetCore.Mvc.Razor.TagHelpers;
@inject ITagHelperComponentManager manager;
@{
string markup;
if (Model.IsWeekend)
{
markup = "<em class='text-warning'>Office closed today!</em>";
}
else
{
markup = "<em class='text-info'>Office open today!</em>";
}
manager.Components.Add(new AddressTagHelperComponent(markup, 1));
}
В предыдущем коде:
- Директива
@inject
предоставляет экземплярITagHelperComponentManager
. Экземпляр назначается переменной с именемmanager
для доступа внизу Razor в файле. - Экземпляр
AddressTagHelperComponent
добавляется в коллекцию вспомогательных компонентов тегов.
В AddressTagHelperComponent
вносятся изменения для создания конструктора, который принимает параметры markup
и order
:
private readonly string _markup;
public override int Order { get; }
public AddressTagHelperComponent(string markup = "", int order = 1)
{
_markup = markup;
Order = order;
}
Предоставленный параметр markup
используется в ProcessAsync
следующим образом:
public override async Task ProcessAsync(TagHelperContext context,
TagHelperOutput output)
{
if (string.Equals(context.TagName, "address",
StringComparison.OrdinalIgnoreCase) &&
output.Attributes.ContainsName("printable"))
{
TagHelperContent childContent = await output.GetChildContentAsync();
string content = childContent.GetContent();
output.Content.SetHtmlContent(
$"<div>{content}<br>{_markup}</div>{_printableButton}");
}
}
Регистрация с помощью модели страницы или контроллера
Если компонент вспомогательной Razor функции тега не зарегистрирован в di, его можно зарегистрировать в модели страниц страницы или контроллере MVC. Этот метод полезен для разделения логики C# от Razor файлов.
Для доступа к экземпляру ITagHelperComponentManager
внедряется конструктор. Вспомогательный компонент тегов добавляется в коллекцию вспомогательных компонентов тегов. Razor Следующая модель страницы Pages демонстрирует этот метод со AddressTagHelperComponent
следующими способами:
using System;
using Microsoft.AspNetCore.Mvc.Razor.TagHelpers;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RazorPagesSample.TagHelpers;
public class IndexModel : PageModel
{
private readonly ITagHelperComponentManager _tagHelperComponentManager;
public bool IsWeekend
{
get
{
var dayOfWeek = DateTime.Now.DayOfWeek;
return dayOfWeek == DayOfWeek.Saturday ||
dayOfWeek == DayOfWeek.Sunday;
}
}
public IndexModel(ITagHelperComponentManager tagHelperComponentManager)
{
_tagHelperComponentManager = tagHelperComponentManager;
}
public void OnGet()
{
string markup;
if (IsWeekend)
{
markup = "<em class='text-warning'>Office closed today!</em>";
}
else
{
markup = "<em class='text-info'>Office open today!</em>";
}
_tagHelperComponentManager.Components.Add(
new AddressTagHelperComponent(markup, 1));
}
}
В предыдущем коде:
- Для доступа к экземпляру
ITagHelperComponentManager
внедряется конструктор. - Экземпляр
AddressTagHelperComponent
добавляется в коллекцию вспомогательных компонентов тегов.
Создание компонента
Чтобы создать пользовательский вспомогательный компонент тегов, выполните следующие действия:
- Создайте открытый класс, который наследует от TagHelperComponentTagHelper.
- Примените атрибут
[HtmlTargetElement]
к классу. Укажите имя целевого элемента HTML. - Необязательно. Примените
[EditorBrowsable(EditorBrowsableState.Never)]
атрибут к классу, чтобы отключить отображение типа в IntelliSense.
Следующий код позволяет создать пользовательский вспомогательный компонент тегов, который работает с элементом HTML <address>
:
using System.ComponentModel;
using Microsoft.AspNetCore.Mvc.Razor.TagHelpers;
using Microsoft.AspNetCore.Razor.TagHelpers;
using Microsoft.Extensions.Logging;
namespace RazorPagesSample.TagHelpers
{
[HtmlTargetElement("address")]
[EditorBrowsable(EditorBrowsableState.Never)]
public class AddressTagHelperComponentTagHelper : TagHelperComponentTagHelper
{
public AddressTagHelperComponentTagHelper(
ITagHelperComponentManager componentManager,
ILoggerFactory loggerFactory) : base(componentManager, loggerFactory)
{
}
}
}
С помощью настраиваемого вспомогательного компонента тегов address
внедрите HTML-разметку, как указано ниже:
public class AddressTagHelperComponent : TagHelperComponent
{
private readonly string _printableButton =
"<button type='button' class='btn btn-info' onclick=\"window.open(" +
"'https://binged.it/2AXRRYw')\">" +
"<span class='glyphicon glyphicon-road' aria-hidden='true'></span>" +
"</button>";
public override int Order => 3;
public override async Task ProcessAsync(TagHelperContext context,
TagHelperOutput output)
{
if (string.Equals(context.TagName, "address",
StringComparison.OrdinalIgnoreCase) &&
output.Attributes.ContainsName("printable"))
{
var content = await output.GetChildContentAsync();
output.Content.SetHtmlContent(
$"<div>{content.GetContent()}</div>{_printableButton}");
}
}
}
Приведенный выше метод ProcessAsync
позволяет внедрить предоставленный в SetHtmlContent HTML-код в соответствующий элемент <address>
. Внедрение происходит при следующих условиях:
- Свойство
TagName
контекста выполнения совпадает со значениемaddress
. - Соответствующий элемент
<address>
имеет атрибутprintable
.
Например, инструкция if
возвращает значение TRUE при обработке следующего элемента <address>
:
<address printable>
One Microsoft Way<br />
Redmond, WA 98052-6399<br />
<abbr title="Phone">P:</abbr>
425.555.0100
</address>
Дополнительные ресурсы
ASP.NET Core
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по