ASP.NET Core의 앵커 태그 도우미

작성자: Peter KellnerScott Addie

앵커 태그 도우미는 새로운 특성을 추가함으로써 표준 HTML 앵커(<a ... ></a>) 태그를 향상시킵니다. 규칙에 따라 해당 특성들의 이름은 asp- 접두사로 시작합니다. 렌더링 되는 앵커 요소의 href 특성 값은 asp- 특성들의 값에 따라 결정됩니다.

태그 도우미에 대한 개요는 ASP.NET Core의 태그 도우미를 참조하세요.

샘플 코드 보기 및 다운로드(다운로드 방법)

이 문서의 예제 전반에서는 다음의 SpeakerController가 사용됩니다.

using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Linq;

public class SpeakerController : Controller
{
    private List<Speaker> Speakers =
        new List<Speaker>
        {
            new Speaker {SpeakerId = 10},
            new Speaker {SpeakerId = 11},
            new Speaker {SpeakerId = 12}
        };

    [Route("Speaker/{id:int}")]
    public IActionResult Detail(int id) =>
        View(Speakers.FirstOrDefault(a => a.SpeakerId == id));

    [Route("/Speaker/Evaluations", 
           Name = "speakerevals")]
    public IActionResult Evaluations() => View();

    [Route("/Speaker/EvaluationsCurrent",
           Name = "speakerevalscurrent")]
    public IActionResult Evaluations(
        int speakerId,
        bool currentYear) => View();

    public IActionResult Index() => View(Speakers);
}

public class Speaker
{
    public int SpeakerId { get; set; }
}

앵커 태그 도우미 특성

asp-controller

asp-controller 특성은 URL 생성에 사용되는 컨트롤러를 지정합니다. 다음 태그는 모든 스피커를 나열합니다.

<a asp-controller="Speaker"
   asp-action="Index">All Speakers</a>

생성되는 HTML은 다음과 같습니다.

<a href="/Speaker">All Speakers</a>

asp-controller 특성이 지정되고 asp-action이 지정되지 않으면, 기본 asp-action 값은 현재 실행 중인 보기와 연결된 컨트롤러 작업입니다. 이전 태그에서 asp-action이 생략되고 HomeControllerIndex 뷰(/Home)에서 앵커 태그 도우미가 사용되는 경우 생성되는 HTML은 다음과 같습니다.

<a href="/Home">All Speakers</a>

asp-action

asp-action 특성값은 생성되는 href 특성에 포함될 컨트롤러 액션의 이름을 나타냅니다. 다음 태그는 생성되는 href 특성 값을 스피커 평가 페이지로 설정합니다.

<a asp-controller="Speaker"
   asp-action="Evaluations">Speaker Evaluations</a>

생성되는 HTML은 다음과 같습니다.

<a href="/Speaker/Evaluations">Speaker Evaluations</a>

asp-controller 특성이 지정되지 않으면 현재 보기를 실행하는 보기를 호출하는 기본 컨트롤러가 사용됩니다.

asp-action 특성값이 Index면 URL에 아무런 액션도 추가되지 않으며 기본 Index 액션이 호출됩니다. 지정된(또는 기본값으로 설정된) 작업은 asp-controller에서 참조되는 컨트롤러에 있어야 합니다.

asp-route-{value}

asp-route-{value} 특성은 와일드카드 경로 접두사를 사용하도록 설정합니다. {value} 자리 표시자에 위치하는 모든 값은 잠재적인 경로 매개 변수로 해석됩니다. 기본 경로가 발견되지 않으면 이 경로 접두사는 생성되는 href 특성에 요청 매개 변수 및 값으로 추가됩니다. 그렇지 않으면 경로 템플릿에서 이 경로 접두사가 대체됩니다.

다음 컨트롤러 작업을 고려해보세요.

private List<Speaker> Speakers =
    new List<Speaker>
    {
        new Speaker {SpeakerId = 10},
        new Speaker {SpeakerId = 11},
        new Speaker {SpeakerId = 12}
    };

[Route("Speaker/{id:int}")]
public IActionResult Detail(int id) =>
    View(Speakers.FirstOrDefault(a => a.SpeakerId == id));

Startup.Configure에 정의된 기본 경로 템플릿을 사용할 경우:

app.UseMvc(routes =>
{
    // need route and attribute on controller: [Area("Blogs")]
    routes.MapRoute(name: "mvcAreaRoute",
                    template: "{area:exists}/{controller=Home}/{action=Index}");

    // default route for non-areas
    routes.MapRoute(
        name: "default",
        template: "{controller=Home}/{action=Index}/{id?}");
});

다음과 같이 MVC 보기가 작업을 통해서 제공되는 모델을 사용하면:

@model Speaker
<!DOCTYPE html>
<html>
<body>
    <a asp-controller="Speaker"
       asp-action="Detail" 
       asp-route-id="@Model.SpeakerId">SpeakerId: @Model.SpeakerId</a>
</body>
</html>

기본 경로의 {id?} 자리 표시자가 일치했습니다. 생성되는 HTML은 다음과 같습니다.

<a href="/Speaker/Detail/12">SpeakerId: 12</a>

다음 MVC 보기와 마찬가지로 경로 접두사가 라우팅 템플릿의 일부와 일치하지 않는다고 가정합니다.

@model Speaker
<!DOCTYPE html>
<html>
<body>
    <a asp-controller="Speaker"
       asp-action="Detail"
       asp-route-speakerid="@Model.SpeakerId">SpeakerId: @Model.SpeakerId</a>
<body>
</html>

일치하는 경로에서 speakerid를 찾을 수 없기 때문에 생성되는 HTML은 다음과 같습니다.

<a href="/Speaker/Detail?speakerid=12">SpeakerId: 12</a>

asp-controller 또는 asp-action이 지정되지 않으면 asp-route 특성과 동일한 기본 처리가 수행됩니다.

asp-route

asp-route 특성은 명명된 경로에 직접 연결되는 URL을 만드는 데 사용됩니다. 라우팅 특성을 사용하면 경로에 SpeakerController에서 볼 수 있는 것과 같이 이름을 지정할 수 있고 Evaluations 작업에서처럼 사용할 수 있습니다.

[Route("/Speaker/Evaluations", 
       Name = "speakerevals")]

다음 태그에서 asp-route 특성은 명명된 경로를 참조합니다.

<a asp-route="speakerevals">Speaker Evaluations</a>

앵커 태그 도우미는 /Speaker/Evaluations URL을 사용하여 해당 컨트롤러 액션을 직접 가리키는 경로를 생성합니다. 생성되는 HTML은 다음과 같습니다.

<a href="/Speaker/Evaluations">Speaker Evaluations</a>

asp-route 외에 asp-controller 또는 asp-action을 지정하면 예상과 다른 경로가 생성될 수 있습니다. 경로 충돌을 방지하려면 asp-routeasp-controllerasp-action 특성과 함께 사용하지 않아야 합니다.

asp-all-route-data

asp-all-route-data 특성은 키-값 쌍 사전을 만들 수 있도록 지원해줍니다. 키는 매개 변수 이름이고, 값은 매개 변수 값입니다.

다음 예제에서는 사전이 초기화되어 Razor 보기로 전달됩니다. 또는 모델을 사용하여 데이터를 전달할 수도 있습니다.

@{
var parms = new Dictionary<string, string>
            {
                { "speakerId", "11" },
                { "currentYear", "true" }
            };
}

<a asp-route="speakerevalscurrent"
   asp-all-route-data="parms">Speaker Evaluations</a>

이전 코드로 생성되는 HTML은 다음과 같습니다.

<a href="/Speaker/EvaluationsCurrent?speakerId=11&currentYear=true">Speaker Evaluations</a>

asp-all-route-data 사전은 병합되어 오버로드된 Evaluations 작업의 요구 사항을 충족하는 쿼리 문자열을 생성합니다.

public IActionResult Evaluations() => View();

[Route("/Speaker/EvaluationsCurrent",
       Name = "speakerevalscurrent")]
public IActionResult Evaluations(

사전에 존재하는 키가 경로 매개 변수와 일치하면 경로에서 해당 값이 적절하게 대체됩니다. 반면 일치하지 않는 다른 값은 요청 매개 변수로 생성됩니다.

asp-fragment

asp-fragment 특성은 URL에 추가할 URL 조각을 정의합니다. 앵커 태그 도우미는 해시 문자(#)를 추가합니다. 다음 태그를 살펴보세요.

<a asp-controller="Speaker"
   asp-action="Evaluations"
   asp-fragment="SpeakerEvaluations">Speaker Evaluations</a>

생성되는 HTML은 다음과 같습니다.

<a href="/Speaker/Evaluations#SpeakerEvaluations">Speaker Evaluations</a>

해시 태그는 클라이언트 쪽 앱을 빌드할 때 유용합니다. 다음과 같이 JavaScript에서 손쉽게 만들고 검색하는 데 사용할 수 있습니다.

asp-area

asp-area 특성은 적절한 경로를 설정하는 데 사용되는 영역 이름을 설정합니다. 이어지는 예제는 asp-area 특성이 경로를 다시 매핑하는 방법을 보여줍니다.

Razor Pages에서 사용하는 방법

Razor Pages 영역은 ASP.NET Core 2.1 이상에서 지원됩니다.

다음 디렉터리 계층 구조를 고려해보세요.

  • {Project name}
    • wwwroot
    • Areas
      • 세션
        • 페이지
          • _ViewStart.cshtml
          • Index.cshtml
          • Index.cshtml.cs
    • 페이지

Sessions 영역의 IndexRazor Page를 참조하는 태그는 다음과 같습니다.

<a asp-area="Sessions"
   asp-page="/Index">View Sessions</a>

생성되는 HTML은 다음과 같습니다.

<a href="/Sessions">View Sessions</a>

Razor Pages 앱에서 영역을 지원하려면 Startup.ConfigureServices에서 다음 중 하나를 수행합니다.

MVC에서 사용하는 방법

다음 디렉터리 계층 구조를 고려해보세요.

  • {Project name}
    • wwwroot
    • Areas
      • Blogs
        • 컨트롤러
          • HomeController.cs
        • Views
          • Home
            • AboutBlog.cshtml
            • Index.cshtml
          • _ViewStart.cshtml
    • 컨트롤러

asp-area를 "Blogs"로 설정하면 이 앵커 태그에 연결된 컨트롤러 및 뷰의 경로에 Areas/Blogs 디렉터리가 접두사로 추가됩니다. AboutBlog 보기를 참조하는 태그는 다음과 같습니다.

<a asp-area="Blogs"
   asp-controller="Home"
   asp-action="AboutBlog">About Blog</a>

생성되는 HTML은 다음과 같습니다.

<a href="/Blogs/Home/AboutBlog">About Blog</a>

MVC 앱에서 영역을 지원하려면 경로 템플릿에 해당 영역에 대한 참조가 포함되어야 합니다(존재할 경우). 해당 템플릿은 Startup.Configure에서 routes.MapRoute 메서드 호출의 두 번째 매개 변수로 표시됩니다.

app.UseMvc(routes =>
{
    // need route and attribute on controller: [Area("Blogs")]
    routes.MapRoute(name: "mvcAreaRoute",
                    template: "{area:exists}/{controller=Home}/{action=Index}");

    // default route for non-areas
    routes.MapRoute(
        name: "default",
        template: "{controller=Home}/{action=Index}/{id?}");
});

asp-protocol

asp-protocol 특성은 URL의 프로토콜(예: https)을 지정하는 데 사용됩니다. 예시:

<a asp-protocol="https"
   asp-controller="Home"
   asp-action="About">About</a>

생성되는 HTML은 다음과 같습니다.

<a href="https://localhost/Home/About">About</a>

이 예제의 호스트 이름은 localhost입니다. 앵커 태그 도우미는 URL을 생성할 때 웹 사이트의 공용 도메인을 사용합니다.

asp-host

asp-host 특성은 URL에 호스트 이름을 지정하는 데 사용됩니다. 예시:

<a asp-protocol="https"
   asp-host="microsoft.com"
   asp-controller="Home"
   asp-action="About">About</a>

생성되는 HTML은 다음과 같습니다.

<a href="https://microsoft.com/Home/About">About</a>

asp-page

asp-page 특성은 Razor Pages와 함께 사용됩니다. 이 특성은 앵커 태그의 href 특성 값을 특정 페이지로 설정하는 데 사용됩니다. 페이지 이름을 / 접두사로 지정하면 앱 루트에서 일치하는 페이지의 URL이 만들어집니다.

샘플 코드를 사용하여 다음 태그는 참석자 Razor Page에 대한 링크를 만듭니다.

<a asp-page="/Attendee">All Attendees</a>

생성되는 HTML은 다음과 같습니다.

<a href="/Attendee">All Attendees</a>

asp-page 특성은 asp-route, asp-controllerasp-action 특성과 상호 배타적입니다. 그러나 다음 태그에서 볼 수 있는 것처럼 asp-pageasp-route-{value}와 함께 사용해서 라우팅을 제어할 수 있습니다.

<a asp-page="/Attendee"
   asp-route-attendeeid="10">View Attendee</a>

생성되는 HTML은 다음과 같습니다.

<a href="/Attendee?attendeeid=10">View Attendee</a>

참조된 페이지가 없으면 요청의 앰비언트 값을 사용하여 현재 페이지에 대한 링크가 생성됩니다. 디버그 로그 수준을 제외하고 경고가 표시되지 않습니다.

asp-page-handler

asp-page-handler 특성은 Razor Pages와 함께 사용됩니다. 이 특성은 특정 페이지 처리기에 연결하기 위한 것입니다.

다음 페이지 처리기를 고려해보세요.

public void OnGetProfile(int attendeeId)
{
    ViewData["AttendeeId"] = attendeeId;

    // code omitted for brevity
}

페이지 모델의 관련 태그는 OnGetProfile 페이지 처리기에 연결됩니다. 페이지 처리기 메서드 이름의 On<Verb> 접두사는 asp-page-handler 특성 값에서 생략됩니다. 비동기 메서드인 경우 Async 접미사도 생략됩니다.

<a asp-page="/Attendee"
   asp-page-handler="Profile"
   asp-route-attendeeid="12">Attendee Profile</a>

생성되는 HTML은 다음과 같습니다.

<a href="/Attendee?attendeeid=12&handler=Profile">Attendee Profile</a>

추가 리소스