ASP.NET Core Blazor 라우팅ASP.NET Core Blazor routing

Luke Latham으로By Luke Latham

요청을 라우팅하는 방법과 Blazor 앱에서 NavLink 구성 요소를 사용하여 탐색 링크를 만드는 방법을 알아봅니다.Learn how to route requests and how to use the NavLink component to create navigation links in Blazor apps.

ASP.NET Core 엔드포인트 라우팅 통합ASP.NET Core endpoint routing integration

Blazor ServerASP.NET Core 엔드포인트 라우팅에 통합됩니다. is integrated into ASP.NET Core Endpoint Routing. Startup.ConfigureMapBlazorHub를 사용하여 대화형 구성 요소에 대해 들어오는 연결을 허용하도록 ASP.NET Core 앱을 구성합니다.An ASP.NET Core app is configured to accept incoming connections for interactive components with MapBlazorHub in Startup.Configure:

app.UseRouting();

app.UseEndpoints(endpoints =>
{
    endpoints.MapBlazorHub();
    endpoints.MapFallbackToPage("/_Host");
});

가장 일반적인 구성은 Blazor Server 앱의 서버 쪽 호스트 역할을 하는 Razor 페이지로 모든 요청을 라우팅하는 것입니다.The most typical configuration is to route all requests to a Razor page, which acts as the host for the server-side part of the Blazor Server app. 규칙에 따라 ‘호스트’ 페이지의 이름은 일반적으로 _Host.cshtml입니다.By convention, the host page is usually named _Host.cshtml. 호스트 파일에 지정된 경로는 경로 일치 시 낮은 우선순위로 작동하기 때문에 ‘대체 경로’라고 합니다.The route specified in the host file is called a fallback route because it operates with a low priority in route matching. 일치하는 다른 경로가 없는 경우 대체(fallback) 경로가 사용됩니다.The fallback route is considered when other routes don't match. 이렇게 하면 앱이 Blazor Server 앱을 방해하지 않고 다른 컨트롤러와 페이지를 사용할 수 있습니다.This allows the app to use others controllers and pages without interfering with the Blazor Server app.

경로 템플릿Route templates

Router 구성 요소는 지정된 경로를 사용하여 각 구성 요소로 라우팅할 수 있도록 합니다.The Router component enables routing to each component with a specified route. Router 구성 요소는 App.razor 파일에 표시됩니다.The Router component appears in the App.razor file:

<Router AppAssembly="typeof(Startup).Assembly">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
    </Found>
    <NotFound>
        <p>Sorry, there's nothing at this address.</p>
    </NotFound>
</Router>

@page 지시문을 포함하는 .razor 파일을 컴파일하면 생성된 클래스에 경로 템플릿을 지정하는 RouteAttribute가 제공됩니다.When a .razor file with an @page directive is compiled, the generated class is provided a RouteAttribute specifying the route template.

런타임에 RouteView 구성 요소는 다음을 수행합니다.At runtime, the RouteView component:

  • 원하는 매개 변수와 함께 Router에서 RouteData를 받습니다.Receives the RouteData from the Router along with any desired parameters.
  • 지정된 매개 변수를 사용하여 지정된 구성 요소를 해당 레이아웃(또는 선택적 기본 레이아웃)으로 렌더링합니다.Renders the specified component with its layout (or an optional default layout) using the specified parameters.

필요한 경우, 레이아웃을 지정하지 않는 구성 요소에 사용할 DefaultLayout 매개 변수를 레이아웃 클래스로 지정할 수 있습니다.You can optionally specify a DefaultLayout parameter with a layout class to use for components that don't specify a layout. 기본 Blazor 템플릿은 MainLayout 구성 요소를 지정합니다.The default Blazor templates specify the MainLayout component. MainLayout.razor는 템플릿 프로젝트의 Shared 폴더에 있습니다.MainLayout.razor is in the template project's Shared folder. 레이아웃에 대한 자세한 내용은 ASP.NET Core Blazor 레이아웃을 참조하세요.For more information on layouts, see ASP.NET Core Blazor 레이아웃.

한 구성 요소에 여러 개의 경로 템플릿을 적용할 수 있습니다.Multiple route templates can be applied to a component. 다음 구성 요소는 /BlazorRoute/DifferentBlazorRoute에 대한 요청에 응답합니다.The following component responds to requests for /BlazorRoute and /DifferentBlazorRoute:

@page "/BlazorRoute"
@page "/DifferentBlazorRoute"

<h1>Blazor routing</h1>

중요

URL을 올바르게 확인하려면 앱의 wwwroot/index.html 파일(Blazor WebAssembly) 또는 Pages/_Host.cshtml 파일(Blazor Server)에 <base> 태그가 있어야 하고, 앱 기본 경로가 href 특성에 지정되어 있어야 합니다(<base href="/">).For URLs to resolve correctly, the app must include a <base> tag in its wwwroot/index.html file (Blazor WebAssembly) or Pages/_Host.cshtml file (Blazor Server) with the app base path specified in the href attribute (<base href="/">). 자세한 내용은 ASP.NET Core 호스트 및 배포 Blazor를 참조하세요.For more information, see ASP.NET Core 호스트 및 배포 Blazor.

콘텐츠를 찾을 수 없는 경우 사용자 지정 콘텐츠 제공Provide custom content when content isn't found

Router 구성 요소를 사용하면 요청된 경로의 콘텐츠를 찾을 수 없는 경우 앱에서 사용자 지정 콘텐츠를 지정할 수 있습니다.The Router component allows the app to specify custom content if content isn't found for the requested route.

App.razor 파일에서 Router 구성 요소의 NotFound 템플릿 매개 변수에 사용자 지정 콘텐츠를 설정합니다.In the App.razor file, set custom content in the NotFound template parameter of the Router component:

<Router AppAssembly="typeof(Startup).Assembly">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
    </Found>
    <NotFound>
        <h1>Sorry</h1>
        <p>Sorry, there's nothing at this address.</p> b
    </NotFound>
</Router>

<NotFound> 태그의 콘텐츠에는 다른 대화형 구성 요소와 같은 임의 항목을 포함할 수 있습니다.The content of <NotFound> tags can include arbitrary items, such as other interactive components. NotFound 콘텐츠에 기본 레이아웃을 적용하려면 ASP.NET Core Blazor 레이아웃을 참조하세요.To apply a default layout to NotFound content, see ASP.NET Core Blazor 레이아웃.

여러 어셈블리에서 구성 요소로 라우팅Route to components from multiple assemblies

AdditionalAssemblies 매개 변수를 사용하여 라우팅 가능한 구성 요소를 검색할 때 고려할 추가 어셈블리를 Router 구성 요소에 대해 지정할 수 있습니다.Use the AdditionalAssemblies parameter to specify additional assemblies for the Router component to consider when searching for routable components. 지정한 어셈블리는 AppAssembly에서 지정한 어셈블리에 추가로 고려됩니다.Specified assemblies are considered in addition to the AppAssembly-specified assembly. 다음 예제에서 Component1은 참조된 클래스 라이브러리에서 정의된 라우팅 가능한 구성 요소입니다.In the following example, Component1 is a routable component defined in a referenced class library. 다음 AdditionalAssemblies 예제에서는 Component1에 대해 라우팅 지원이 생성됩니다.The following AdditionalAssemblies example results in routing support for Component1:

<Router
    AppAssembly="typeof(Program).Assembly"
    AdditionalAssemblies="new[] { typeof(Component1).Assembly }">
    ...
</Router>

경로 매개 변수Route parameters

라우터는 경로 매개 변수를 사용하여 해당 구성 요소 매개 변수를 동일한 이름(대/소문자 구분 안 함)으로 채웁니다.The router uses route parameters to populate the corresponding component parameters with the same name (case insensitive):

@page "/RouteParameter"
@page "/RouteParameter/{text}"

<h1>Blazor is @Text!</h1>

@code {
    [Parameter]
    public string Text { get; set; }

    protected override void OnInitialized()
    {
        Text = Text ?? "fantastic";
    }
}

선택적 매개 변수는 지원되지 않습니다.Optional parameters aren't supported. 위의 예제에서는 두 개의 @page 지시문이 적용되었습니다.Two @page directives are applied in the previous example. 첫 번째 지시문은 매개 변수 없이 구성 요소 탐색을 허용합니다.The first permits navigation to the component without a parameter. 두 번째 @page 지시문은 {text} 경로 매개 변수를 사용하고 Text 속성에 값을 할당합니다.The second @page directive takes the {text} route parameter and assigns the value to the Text property.

경로 제약 조건Route constraints

경로 제약 조건은 경로 세그먼트의 형식 일치를 구성 요소에 적용합니다.A route constraint enforces type matching on a route segment to a component.

다음 예제에서 Users 구성 요소의 경로는 다음과 같은 경우에만 일치합니다.In the following example, the route to the Users component only matches if:

  • 요청 URL에 Id 경로 세그먼트가 있는 경우An Id route segment is present on the request URL.
  • Id 세그먼트가 정수(int)인 경우The Id segment is an integer (int).
@page "/Users/{Id:int}"

<h1>The user Id is @Id!</h1>

@code {
    [Parameter]
    public int Id { get; set; }
}

다음 표에 나와 있는 경로 제약 조건을 사용할 수 있습니다.The route constraints shown in the following table are available. 고정 문화권과 일치하는 경로 제약 조건에 대한 자세한 내용은 표 아래에 있는 경고를 참조하세요.For the route constraints that match with the invariant culture, see the warning below the table for more information.

제약 조건Constraint 예제Example 일치하는 예제Example Matches 고정Invariant
cultureculture
일치matching
bool {active:bool} true, FALSEtrue, FALSE 아니요No
datetime {dob:datetime} 2016-12-31, 2016-12-31 7:32pm2016-12-31, 2016-12-31 7:32pm Yes
decimal {price:decimal} 49.99, -1,000.0149.99, -1,000.01 Yes
double {weight:double} 1.234, -1,001.01e81.234, -1,001.01e8 Yes
float {weight:float} 1.234, -1,001.01e81.234, -1,001.01e8 Yes
guid {id:guid} CD2C1638-1638-72D5-1638-DEADBEEF1638, {CD2C1638-1638-72D5-1638-DEADBEEF1638}CD2C1638-1638-72D5-1638-DEADBEEF1638, {CD2C1638-1638-72D5-1638-DEADBEEF1638} 아니요No
int {id:int} 123456789, -123456789123456789, -123456789 Yes
long {ticks:long} 123456789, -123456789123456789, -123456789 Yes

경고

CLR 형식(예: int 또는 DateTime)으로 변환되는 URL을 확인하는 경로 제약 조건은 항상 고정 문화권을 사용합니다.Route constraints that verify the URL and are converted to a CLR type (such as int or DateTime) always use the invariant culture. 이러한 제약 조건은 URL은 지역화될 수 없다고 가정합니다.These constraints assume that the URL is non-localizable.

점이 포함된 URL을 사용한 라우팅Routing with URLs that contain dots

Blazor Server 앱에서 _Host.cshtml의 기본 경로는 /(@page "/")입니다.In Blazor Server apps, the default route in _Host.cshtml is / (@page "/"). 점(.)이 포함된 요청 URL은 URL이 파일을 요청하는 것 같으므로 기본 경로와 일치되지 않습니다.A request URL that contains a dot (.) isn't matched by the default route because the URL appears to request a file. Blazor 앱은 존재하지 않는 정적 파일에 대해 404 - 찾을 수 없음 응답을 반환합니다.A Blazor app returns a 404 - Not Found response for a static file that doesn't exist. 점이 포함된 경로를 사용하려면 다음 경로 템플릿을 통해 _Host.cshtml을 구성합니다.To use routes that contain a dot, configure _Host.cshtml with the following route template:

@page "/{**path}"

"/{**path}" 템플릿에는 다음이 포함되어 있습니다.The "/{**path}" template includes:

  • 슬래시(/)를 인코딩하지 않고 여러 폴더 경계에 걸쳐 있는 경로를 캡처하기 위한 이중 별표 catch-all 구문(**)Double-asterisk catch-all syntax (**) to capture the path across multiple folder boundaries without encoding forward slashes (/).
  • path 경로 매개 변수 이름path route parameter name.

참고

Catch-all 매개 변수 구문(*/**)은 Razor 구성 요소(.razor)에서 지원되지 않습니다.Catch-all parameter syntax (*/**) is not supported in Razor components (.razor).

자세한 내용은 ASP.NET Core에서 라우팅를 참조하세요.For more information, see ASP.NET Core에서 라우팅.

탐색 링크를 만드는 경우 HTML 하이퍼링크 요소(<a>) 대신 NavLink 구성 요소를 사용합니다.Use a NavLink component in place of HTML hyperlink elements (<a>) when creating navigation links. NavLink 구성 요소는 href가 현재 URL과 일치하는지 아닌지에 따라 active CSS 클래스를 전환한다는 점을 제외하고 <a> 요소처럼 동작합니다.A NavLink component behaves like an <a> element, except it toggles an active CSS class based on whether its href matches the current URL. active 클래스는 사용자가 표시되는 탐색 링크 중에서 활성 페이지를 파악하는 데 도움이 됩니다.The active class helps a user understand which page is the active page among the navigation links displayed.

다음 NavMenu 구성 요소는 NavLink 구성 요소를 사용하는 방법을 보여 주는 Bootstrap 탐색 모음을 만듭니다.The following NavMenu component creates a Bootstrap navigation bar that demonstrates how to use NavLink components:

<div class="@NavMenuCssClass" @onclick="@ToggleNavMenu">
    <ul class="nav flex-column">
        <li class="nav-item px-3">
            <NavLink class="nav-link" href="" Match="NavLinkMatch.All">
                <span class="oi oi-home" aria-hidden="true"></span> Home
            </NavLink>
        </li>
        <li class="nav-item px-3">
            <NavLink class="nav-link" href="MyComponent" Match="NavLinkMatch.Prefix">
                <span class="oi oi-plus" aria-hidden="true"></span> My Component
            </NavLink>
        </li>
    </ul>
</div>

<NavLink> 요소의 Match 특성에 할당할 수 있는 다음 두 가지 NavLinkMatch 옵션이 있습니다.There are two NavLinkMatch options that you can assign to the Match attribute of the <NavLink> element:

위의 예제에서 홈 NavLink href=""는 홈 URL과 일치하고, 앱의 기본 경로 URL(예: https://localhost:5001/)에 있는 active CSS 클래스만 받습니다.In the preceding example, the Home NavLink href="" matches the home URL and only receives the active CSS class at the app's default base path URL (for example, https://localhost:5001/). 두 번째 NavLink는 사용자가 MyComponent 접두사를 포함하는 URL(예: https://localhost:5001/MyComponenthttps://localhost:5001/MyComponent/AnotherSegment)을 방문할 때 active 클래스를 받습니다.The second NavLink receives the active class when the user visits any URL with a MyComponent prefix (for example, https://localhost:5001/MyComponent and https://localhost:5001/MyComponent/AnotherSegment).

추가 NavLink 구성 요소 특성이 렌더링된 앵커 태그로 전달됩니다.Additional NavLink component attributes are passed through to the rendered anchor tag. 다음 예제에서 NavLink 구성 요소는 target 특성을 포함합니다.In the following example, the NavLink component includes the target attribute:

<NavLink href="my-page" target="_blank">My page</NavLink>

다음 HTML 태그가 렌더링됩니다.The following HTML markup is rendered:

<a href="my-page" target="_blank" rel="noopener noreferrer">My page</a>

URI 및 탐색 상태 도우미URI and navigation state helpers

NavigationManager를 사용하여 C# 코드로 URI 및 탐색 작업을 수행할 수 있습니다.Use NavigationManager to work with URIs and navigation in C# code. NavigationManager는 다음 표에 나와 있는 이벤트와 메서드를 제공합니다.NavigationManager provides the event and methods shown in the following table.

멤버Member 설명Description
Uri 현재 절대 URI를 가져옵니다.Gets the current absolute URI.
BaseUri 절대 URI를 생성하기 위해 상대 URI 경로 앞에 추가할 수 있는 기본 URI(후행 슬래시 포함)를 가져옵니다.Gets the base URI (with a trailing slash) that can be prepended to relative URI paths to produce an absolute URI. 일반적으로 BaseUriwwwroot/index.html(Blazor WebAssembly) 또는 Pages/_Host.cshtml(Blazor Server)에 있는 문서 <base> 요소의 href 특성에 해당합니다.Typically, BaseUri corresponds to the href attribute on the document's <base> element in wwwroot/index.html (Blazor WebAssembly) or Pages/_Host.cshtml (Blazor Server).
NavigateTo 지정한 URI로 이동합니다.Navigates to the specified URI. forceLoadtrue인 경우If forceLoad is true:
  • 클라이언트 쪽 라우팅이 무시됩니다.Client-side routing is bypassed.
  • 클라이언트 쪽 라우터에서 URI를 정상적으로 처리했는지와 상관없이 브라우저에서 서버의 새 페이지를 강제로 로드합니다.The browser is forced to load the new page from the server, whether or not the URI is normally handled by the client-side router.
LocationChanged 탐색 위치가 변경된 경우에 발생하는 이벤트입니다.An event that fires when the navigation location has changed.
ToAbsoluteUri 상대 URI를 절대 URI로 변환합니다.Converts a relative URI into an absolute URI.
ToBaseRelativePath 기본 URI(예: 이전에 BaseUri에서 반환된 URI)가 제공된 경우, 절대 URI를 기본 URI 접두사의 상대 URI로 변환합니다.Given a base URI (for example, a URI previously returned by BaseUri), converts an absolute URI into a URI relative to the base URI prefix.

단추를 선택하면 다음 구성 요소가 앱의 Counter 구성 요소로 이동합니다.The following component navigates to the app's Counter component when the button is selected:

@page "/navigate"
@inject NavigationManager NavigationManager

<h1>Navigate in Code Example</h1>

<button class="btn btn-primary" @onclick="NavigateToCounterComponent">
    Navigate to the Counter component
</button>

@code {
    private void NavigateToCounterComponent()
    {
        NavigationManager.NavigateTo("counter");
    }
}

다음 구성 요소는 NavigationManager.LocationChanged을 설정하여 위치 변경 이벤트를 처리합니다.The following component handles a location changed event by setting NavigationManager.LocationChanged. HandleLocationChanged 메서드는 프레임워크에서 Dispose를 호출할 때 언후크됩니다.The HandleLocationChanged method is unhooked when Dispose is called by the framework. 메서드를 언후크하면 구성 요소의 가비지 수집이 허용됩니다.Unhooking the method permits garbage collection of the component.

@implements IDisposable
@inject NavigationManager NavigationManager

...

protected override void OnInitialized()
{
    NavigationManager.LocationChanged += HandleLocationChanged;
}

private void HandleLocationChanged(object sender, LocationChangedEventArgs e)
{
    ...
}

public void Dispose()
{
    NavigationManager.LocationChanged -= HandleLocationChanged;
}

LocationChangedEventArgs는 이벤트에 대해 다음과 같은 정보를 제공합니다.LocationChangedEventArgs provides the following information about the event:

구성 요소 삭제에 대한 자세한 내용은 ASP.NET Core Blazor 수명 주기을 참조하세요.For more information on component disposal, see ASP.NET Core Blazor 수명 주기.