[ASP.NET Core] 태그헬퍼

2018. 11. 15. 12:17WEB/ASP.NET Core

태그헬퍼(Tag Helper)

  • ASP.NET Core에서 처음 소개되었으며 Razor에서 HTML렌더링을 도와주는 서버코드
  • ASP.NET MVC의 헬퍼메서드와 유사한 기능을 하며 태그형태로 사용가능
  • 대부분 asp-* 접미사로 시작함
태그헬퍼: <label asp-for="Person.Name"></label>
실행결과: <label for="Person_Name">Name</label>

태그헬퍼의 이점

  • VisualStudio가 아닌 텍스트편집기에서도 SyntaxHighlighter, 자동완성 기능을 사용할 수 있음
  • C# 문법을 몰라도 친숙한 HTML 문법으로 View작성가능

태그헬퍼의 Scope

#사용선언: @addTagHelper

태그헬퍼를 Razor View에서 사용하려면 @addTagHelper 키워드를 통해 사용선언 필요
전체 Page에 영향을 미치는 Pages/_ViewImports.cshtml 파일을 열어보면 아래 코드를 포함하고 있음

@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

@addTagHelper의 첫 번째 매개변수 *은 사용할 TagHelper의 Class Name을 의미하고
두 번째 매개변수 Microsoft.AspNetCore.Mvc.TagHelpers는 Assembly Name을 의미함

위 코드 때문에 전체 Razir View에서 태그헬퍼를 사용할 수 있는 것이며, 사용자정의 태그헬퍼도 추가할 수 있음

//참고: Class Name에는 '*' 와일드카드를 사용할 수 있음
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper TagHelpers.EmailTagHelper, NsMyTagHelpers
@addTagHelper TagHelpers.TagHelper*,  NsTagHelpers

#비활성화: @removeTagHelper

태그헬퍼 사용을 중단해야 할 때 사용
사용방법은 addTagHelper와 동일함

#옵트아웃: !

! 문자를 사용하여 태그헬퍼를 인라인에서 비활성화 할 수 있음
아래코드는 태그헬퍼 asp-validation-for가 동작하지 않고 그대로 HTML로 출력됨

작성: <!span asp-validation-for="Email"></!span>
결과: <span asp-validation-for="Email"></span>

#태그헬퍼 접두사: @tagHelperPrefix

태그헬퍼 사용을 명시적으로 표현하고 싶은 경우 접두사를 지정할 수 있음
접두사를 통해 태그헬퍼를 사용을 명시적으로 표현할 수 있음

@tagHelperPrefix th:
<th:span asp-validation-for="Email"></th:span>

사용자정의 태그헬퍼 작성

태그헬퍼는 ITagHelper Interface의 구현체를 말함
사용자정의 태그헬퍼는 ITagHelper 대신 TagHelper Class를 상속하여 구현 함

내장 태그헬퍼

#1 Anchor Tag Helper

구문 설명
asp-controller
asp-action
MVC Routing 설정
작성: <a asp-controller="Books" asp-action="View">Books/View</a>
결과: <a href="/Books/View">Books</a>
asp-fragment Bookmark 설정 (#)
작성: <a asp-controller="Books" asp-fragment="List">Books#List</a>
결과: <a href="/Books#List">Books#List</a>
asp-protocol http, https 등의 프로토콜명 지정
작성: <a asp-controller="Books" asp-fragment="List">Books#List</a>
결과: <a href="/Books#List">Books#List</a>
asp-host Hostname 설정
작성: <a asp-controller="Books" asp-host="test.com">Books</a>
결과: <a href="http://test.com/Books">Books</a>
asp-route Rout Name을 통한 경로설정
[Route(Name = "booksView")] //Route Name 설정
public IActionResult Details()
{
    return View();
}
작성: <a asp-route="booksView">booksView</a>
결과: <a href="/Books/View">Books</a>
asp-route-* 요청 매개변수 설정 (주의: action, controller, page 등 몇가지 키워드는 사용불가)
작성: <a asp-controller="Books" asp-route-id="1" asp-route-pageNumber="3">Books</a>
결과: <a href="/Books?id=1&pageNumber=3">Books</a>
asp-page RazorPage 경로설정
작성: <a asp-page="/People">People</a>
결과: <a href="/People">People</a>
asp-page-handler RazorPage의 handler 설정
작성: <a asp-page="/People" asp-page-handler="Profile">People Profile</a>
결과: <a href="/People?handler=Profile">People Profile</a>

#2 Form Tag Helper

form의 경로설정은 anchor 태그헬퍼와 동일함
form은 RequestVerificationToken Hidden 필드를 자동생성함 ([ValidateAntiForgeryToken] Attribute와 함께 사용시 CSRF(Cross-site Request Forgery)공격 방지)

<!-- Razor 구문 -->
<form asp-controller="Account" asp-action="Register" method="post">

</form>

<!-- 생성된 HTML -->
<form method="post" action="/Demo/Register">
    <input name="__RequestVerificationToken" type="hidden" value="CfDJ8OfzKM3lQEVHu0PCeJHBLiZElU80VQu7_-T_S6zfAvYCcFiSukctf9iL9Vf9i_0Yoy9iT3NT8MCD63dQMb3VdvwhGAjtahaTGZcWysn3j42-I4SjmNMtPODPCATXoz-UG4LI4OKpu4CKSvMcFDhWPT0" />
</form>

#3 Input Tag Helper

기본적으로 헬퍼 메서드 Html.EditorFor()와 동일함
Model의 변수유형, DataType, DataAnnotations(Required, Maxlength 등)에 따라서 적절한 HTML이 렌더링됨

<!-- Razor 구문 -->
<input asp-for="Email" />

<!-- 생성된 HTML -->
<input type="email" data-val="true" data-val-maxlength="The field Email must be a string or array type with a maximum length of '200'." data-val-maxlength-max="200" id="Email" name="Email" value="">

생성될 HTML Attribute를 직접 지정할 수 있음

<!-- Razor 구문 -->
<input asp-for="Email" type="text" id="UserEmail" value="test@@test.com" data-val-maxlength="Please enter less than 200 letters" />

<!-- 생성된 HTML -->
<input type="text" id="UserEmail" value="sample@sample.com" data-val-maxlength="Please enter less than 200 letters" data-val-maxlength-max="200" name="Email">

#4 TextArea, Label Tag Helper

기본적으로 헬퍼 메서드 Html.LabelFor(), Html.TextAreaFor()와 동일함
Model의 변수유형, DataType, DataAnnotations(Required, Maxlength 등)에 따라서 적절한 HTML이 렌더링됨
생성될 HTML Attribute를 직접 지정할 수 있음

<!-- Raozr 구문 -->
<label asp-for="Note"></label>
<textarea asp-for="Note"></textarea>

<!-- 생성된 HTML -->
<label for="Note">Note</label>
<textarea data-val="true" data-val-maxlength="The field Note must be a string or array type with a maximum length of '200'." data-val-maxlength-max="200" id="Note" name="Note"></textarea>

#5 Select Tag Helper

헬퍼 메서드 Html.DropDownListFor()와 유사함
생성될 HTML Attribute를 직접 지정할 수 있음
좀더 구체적인 사례들은 MS 자습서 참고

<!-- Enum 선언 -->
public enum NationalityTypes
{
    [Display(Name = "Republic of Korea")]
    Korea = 1,
    USA = 2
}

<!-- Razor 구문 -->
<select asp-for="Nationality" asp-items="Html.GetEnumSelectList<NationalityTypes>()">
    <option disabled="disabled" selected="selected">--- 국적선택---</option>
</select>

<!-- 생성된 HTML -->
<select id="Nationality" name="Nationality">
    <option disabled="disabled" selected="selected">--- 국적선택---</option>
    <option value="1">Republic of Korea</option>
    <option value="2">USA</option>
</select>

#6 Validation Tag Helper

헬퍼 메서드 Html.ValidationMessageFor(), Html.ValidationSummary()와 유사함

<!-- Razor 구문 -->
<input asp-for="BirthDate" />
<span asp-validation-for="BirthDate"></span>
<div asp-validation-summary=" All"></div>

<!-- 생성된 HTML -->
<input type="date" id="BirthDate" name="BirthDate" value="">
<span class="field-validation-valid" data-valmsg-for="BirthDate" data-valmsg-replace="true"></span>
<div class="validation-summary-valid" data-valmsg-summary="true">
    <ul><li style="display:none"></li></ul>
</div>

#7 Image Tag Helper

Image 경로 설정 시 Server 경로 설정가능
asp-append-version="true"를 통해 Cash-busting을 활성화 시킬 수 있음
(참고: Cash-busting이란 서버의 파일이 변경되었을 때 브라우저의 캐시기능을 무력화시켜 변경된 파일을 내려받도록 하는 기능)

<!-- Razor 구문 -->
<img src="~/images/logo.png" asp-append-version="true" />

<!-- 생성된 HTML -->
<img src="/images/logo.png?v=57Kl8Qj_Fheudclvdct_s5HLj_Bgof4q3hSTuBY226I">

쿼리스트링 v=의 값은 Sha512 문자열로 이미지가 업데이트 될 때마다 갱신됨
이미지가 업데이트되면 Sha512 문자열이 변경되므로 브라우저의 캐시기능이 무력화 됨

#8 Partial Tag Helper

Html.RenderPartial()과 동일하게 동작함

<!-- Razor 구문 -->
<partial name="_LoginPartial" for="@Model" view-data="ViewData" />

#9 Environment Tag Helper

ASP.NET Core의 launchSettings.json에서 설정가능한 환경변수 ASPNETCORE_ENVIRONMENT에 설정된 값에 따라 선택적으로 컨텐트를 렌더링
환경변수 설정방법은 MS 자습서 참고

[names] names에 지정한 값 중 하나라도 HostingEnvironment.EnvironmentName의 값과 일치하는 경우 출력됨
<environment names="Staging,Production">
	<strong>HostingEnvironment.EnvironmentName 값이 Staging 또는 Production인 경우 출력됨</strong>
</environment>

[include] name과 동일
<environment include="Staging,Production">
	<strong>HostingEnvironment.EnvironmentName 값이 Staging 또는 Production인 경우 출력됨</strong>
</environment>

[exclude] names에 지정한 값 중 하나라도 HostingEnvironment.EnvironmentName의 값과 일치하는 경우 출력제외
<environment exclude="Development,Production">
	<strong>HostingEnvironment.EnvironmentName 값이 Development 또는 Production인 경우 출력제외</strong>
</environment>

name, include, exclude가 동시에 사용될 경우 exclude가 우선순위가 가장 높음 (exclude 값이 일치하면 include에 포함되더라도 출력되지 않음)
환경변수는 Environment.GetEnvironmentVariable() 코드로 조회할 수 있으므로 if/else 구문으로 작성할 수도 있음

@if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development")
{
    @:Development
}
else if(Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Staging")
{
    @:Staging
}

#10 Cache Tag Helper

ASP.NET MVC의 [Cache] Attribute를 Razor View에서 구현가능
자세한 사항은 MS의 자습서 참고

<!-- 다양한 Cache 옵션을 사용할 수 있음 -->
<cache priority="High"
    enabled="true"
    expires-on="@new DateTime(2020, 12, 31)"
    expires-after="@TimeSpan.FromDays(10)"
    expires-sliding="@TimeSpan.FromSeconds(60)" 
    vary-by-header="User-Agent" 
    vary-by-query="q" 
    vary-by-route="Model" 
    vary-by-cookie=".AspNetCore.Identity.Application" 
    vary-by-user="true" vary-by="@Model">
    캐시된 시간: @DateTime.Now
</cache>

References

ASP.NET Core Tag helpers: https://docs.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/intro?view=aspnetcore-2.1