ASP.NET Core의 태그 도우미 구성 요소
작성자: Scott Addie, Fiyaz Bin Hasan
태그 도우미 구성 요소는 서버 쪽 코드에서 HTML 요소를 조건부로 수정하거나 추가할 수 있도록 하는 태그 도우미입니다. 이 기능은 ASP.NET Core 2.0 이상에서 사용할 수 있습니다.
ASP.NET Core에는 두 개의 기본 제공 태그 도우미 구성 요소, 즉 head
및 body
가 포함되어 있습니다. 이 구성 요소는 Microsoft.AspNetCore.Mvc.Razor.TagHelpers 네임스페이스에 있으며 MVC 및 Razor Pages에서 모두 사용할 수 있습니다. 태그 도우미 구성 요소에는 앱 _ViewImports.cshtml
등록이 필요하지 않습니다.
사용 사례
태그 도우미 구성 요소의 두 가지 일반적인 사용 사례는 다음과 같습니다.
다음 섹션에서는 이 사용 사례를 설명합니다.
HTML 헤드 요소에 주입
HTML <head>
요소 내에서 CSS 파일은 일반적으로 HTML <link>
요소로 가져옵니다. 다음 코드는 head
태그 도우미 구성 요소를 사용하여 <head>
요소에 <link>
요소를 주입합니다.
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>
요소를 주입할 수 있습니다. 다음 코드에서는 이 기술을 보여 줍니다.
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);
}
}
}
}
별도의 HTML 파일이 <script>
요소를 저장하는 데 사용됩니다. 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>
위의 코드는 부트스트랩 도구 설명 위젯을 printable
특성을 포함하는 <address>
요소에 바인드합니다. 요소 위에 마우스 포인터를 놓으면 효과가 표시됩니다.
구성 요소 등록
태그 도우미 구성 요소를 앱의 태그 도우미 구성 요소 컬렉션에 추가해야 합니다. 컬렉션에 추가하는 세 가지 방법이 있습니다.
서비스 컨테이너를 통한 등록
태그 도우미 구성 요소 클래스가 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 Pages 페이지 또는 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
의 인스턴스를 제공합니다. 이 인스턴스는 Razor 파일의 다운스트림에 액세스하기 위해manager
라는 변수에 할당됩니다.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}");
}
}
페이지 모델 또는 컨트롤러를 통한 등록
태그 도우미 구성 요소가 DI에 등록되어 있지 않으면 Razor Pages 페이지 모델 또는 MVC 컨트롤러에서 등록할 수 있습니다. 이 기술은 Razor 파일에서 C# 논리를 분리하는 데 유용합니다.
생성자 주입은 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에서 형식이 표시되지 않도록 합니다.
다음 코드는 <address>
HTML 요소를 대상으로 하는 사용자 지정 태그 도우미 구성 요소를 만듭니다.
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
문은 다음 <address>
요소를 처리할 때 true로 평가됩니다.
<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 문제를 단계적으로 폐지하고 이를 새로운 피드백 시스템으로 바꿀 예정입니다. 자세한 내용은 다음을 참조하세요.다음에 대한 사용자 의견 제출 및 보기