ASP.NET Core Blazor 라우팅 및 탐색

이 문서에서는 요청을 라우팅하는 방법과 Blazor 앱에서 NavLink 구성 요소를 사용하여 탐색 링크를 만드는 방법을 설명합니다.

중요

이 문서의 코드 예제에서는 클래스 및 구성 요소에 Navigation삽입된 에 호출된 NavigationManager 메서드를 보여 줍니다.

경로 템플릿

Router 구성 요소를 사용하여 Blazor 앱에서 Razor 구성 요소로 라우팅할 수 있습니다. Router 구성 요소는 Blazor 앱의 App 구성 요소에서 사용됩니다.

App.razor:

<Router AppAssembly="@typeof(Program).Assembly">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
    </Found>
    <NotFound>
        <p>Sorry, there's nothing at this address.</p>
    </NotFound>
</Router>
<Router AppAssembly="@typeof(Program).Assembly">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
    </Found>
    <NotFound>
        <p>Sorry, there's nothing at this address.</p>
    </NotFound>
</Router>
<Router AppAssembly="@typeof(Program).Assembly">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
    </Found>
    <NotFound>
        <p>Sorry, there's nothing at this address.</p>
    </NotFound>
</Router>
<Router AppAssembly="@typeof(Program).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 구성 요소(.razor)를 컴파일하면 생성된 구성요소 클래스에 구성 요소의 경로 템플릿을 지정하는 RouteAttribute가 제공됩니다.

앱이 시작하면 라우터의 AppAssembly로 지정된 어셈블리를 검사하여 RouteAttribute가 있는 앱의 구성 요소에 대한 경로 정보를 수집합니다.

런타임에 RouteView 구성 요소는 다음을 수행합니다.

  • 경로 매개 변수와 함께 Router에서 RouteData를 받습니다.
  • 추가로 중첩된 레이아웃을 포함하여 해당 레이아웃과 함께 지정된 구성 요소를 렌더링합니다.

필요한 경우, @layout 지시문으로 레이아웃을 지정하지 않는 구성 요소에 레이아웃 클래스가 포함된 DefaultLayout 매개 변수를 지정합니다. 프레임워크의 Blazor 프로젝트 템플릿MainLayout 구성 요소(Shared/MainLayout.razor)를 앱의 기본 레이아웃으로 지정합니다. 레이아웃에 대한 자세한 내용은 ASP.NET Core Blazor 레이아웃을 참조하세요.

구성 요소는 여러 @page 지시문을 사용하여 여러 경로 템플릿을 지원합니다. 다음 예제 구성 요소는 /blazor-route/different-blazor-route에 대한 요청을 로드합니다.

Pages/BlazorRoute.razor:

@page "/blazor-route"
@page "/different-blazor-route"

<h1>Blazor routing</h1>
@page "/blazor-route"
@page "/different-blazor-route"

<h1>Blazor routing</h1>
@page "/blazor-route"
@page "/different-blazor-route"

<h1>Blazor routing</h1>
@page "/blazor-route"
@page "/different-blazor-route"

<h1>Blazor routing</h1>

중요

URL을 올바르게 확인하려면 앱에 <base> 태그(<head> 콘텐츠의 위치)가 있어야 하고, 앱 기본 경로가 href 특성에 지정되어 있어야 합니다. 자세한 내용은 ASP.NET Core Blazor 호스트 및 배포를 참조하세요.

Router는 쿼리 문자열 값과 상호 작용하지 않습니다. 쿼리 문자열을 작업하려면 쿼리 문자열 섹션을 참조하세요 .

지시문을 사용하여 경로 템플릿을 문자열 리터럴 @page 로 지정하는 대신 지시문을 사용하여 상수 기반 경로 템플릿을 @attribute지정할 수 있습니다.

다음 예제에서 구성 요소의 @page 지시문은 앱의 @attribute 다른 곳에서 "/counter"로 설정된 의 지시문 및 상수 기반 경로 템플릿Constants.CounterRoute으로 바뀝니다.

- @page "/counter"
+ @attribute [Route(Constants.CounterRoute)]

탐색 요소에 집중

FocusOnNavigate 구성 요소를 사용하여 한 페이지에서 다른 페이지로 이동한 후 CSS 선택기를 기반으로 UI 포커스를 요소로 설정합니다. Blazor 프로젝트 템플릿에서 생성된 앱의 App 구성 요소에서 사용 중인 FocusOnNavigate 구성 요소를 볼 수 있습니다.

App.razor의 경우

<FocusOnNavigate RouteData="@routeData" Selector="h1" />

Router 구성 요소가 새 페이지로 이동하면 FocusOnNavigate 구성 요소는 페이지의 최상위 헤더(<h1>)로 포커스를 설정합니다. 이는 화면 읽기 프로그램을 사용할 때 페이지 탐색이 발표되도록 하기 위한 일반적인 전략입니다.

콘텐츠를 찾을 수 없는 경우 사용자 지정 콘텐츠 제공

Router 구성 요소를 사용하면 요청된 경로의 콘텐츠를 찾을 수 없는 경우 앱에서 사용자 지정 콘텐츠를 지정할 수 있습니다.

App 구성 요소에서 Router 구성 요소의 NotFound 템플릿에 사용자 지정 콘텐츠를 설정합니다.

App.razor:

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

참고

ASP.NET Core 5.0.1 릴리스 및 추가 5.x 릴리스부터 Router 구성 요소에는 @true로 설정된 PreferExactMatches 매개 변수가 포함됩니다. 자세한 내용은 ASP.NET Core 3.1에서 5.0으로 마이그레이션을 참조하세요.

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

다른 대화형 구성 요소와 같은 임의 항목이 <NotFound> 태그의 콘텐츠로 지원됩니다. NotFound 콘텐츠에 기본 레이아웃을 적용하려면 ASP.NET Core Blazor 레이아웃을 참조하세요.

여러 어셈블리에서 구성 요소로 라우팅

AdditionalAssemblies 매개 변수를 사용하여 라우팅 가능한 구성 요소를 검색할 때 고려할 추가 어셈블리를 Router 구성 요소에 대해 지정할 수 있습니다. AppAssembly에 지정된 어셈블리 외에도 추가 어셈블리가 검색됩니다. 다음 예제에서 Component1은 참조된 구성 요소 클래스 라이브러리에서 정의된 라우팅 가능한 구성 요소입니다. 다음 AdditionalAssemblies 예제에서는 Component1에 대해 라우팅 지원이 생성됩니다.

App.razor:

<Router
    AppAssembly="@typeof(App).Assembly"
    AdditionalAssemblies="new[] { typeof(Component1).Assembly }">
    @* ... Router component elements ... *@
</Router>

참고

ASP.NET Core 5.0.1 릴리스 및 추가 5.x 릴리스부터 Router 구성 요소에는 @true로 설정된 PreferExactMatches 매개 변수가 포함됩니다. 자세한 내용은 ASP.NET Core 3.1에서 5.0으로 마이그레이션을 참조하세요.

경로 매개 변수

라우터는 경로 매개 변수를 사용하여 해당 구성 요소 매개 변수를 동일한 이름으로 채웁니다. 경로 매개 변수 이름은 대/소문자를 구분하지 않습니다. 다음 예제에서 text 매개 변수는 경로 세그먼트의 값을 구성 요소의 Text 속성에 할당합니다. /route-parameter-1/amazing에 대한 요청을 수행하면 <h1> 태그 콘텐츠가 Blazor is amazing!으로 렌더링됩니다.

Pages/RouteParameter1.razor:

@page "/route-parameter-1/{text}"

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

@code {
    [Parameter]
    public string? Text { get; set; }
}
@page "/route-parameter-1/{text}"

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

@code {
    [Parameter]
    public string? Text { get; set; }
}
@page "/route-parameter-1/{text}"

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

@code {
    [Parameter]
    public string Text { get; set; }
}
@page "/route-parameter-1/{text}"

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

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

선택적 매개 변수가 지원됩니다. 다음 예제에서 text 선택적 매개 변수는 경로 세그먼트의 값을 구성 요소의 Text 속성에 할당합니다. 세그먼트가 없으면 Text 값이 fantastic으로 설정됩니다.

선택적 매개 변수는 지원되지 않습니다. 다음 예제에서는 두 개의 @page 지시문이 적용되었습니다. 첫 번째 지시문은 매개 변수 없이 구성 요소 탐색을 허용합니다. 두 번째 지시문은 {text} 경로 매개 변수 값을 구성 요소의 Text 속성에 할당합니다.

Pages/RouteParameter2.razor:

@page "/route-parameter-2/{text?}"

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

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

    protected override void OnInitialized()
    {
        Text = Text ?? "fantastic";
    }
}
@page "/route-parameter-2/{text?}"

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

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

    protected override void OnInitialized()
    {
        Text = Text ?? "fantastic";
    }
}
@page "/route-parameter-2/{text?}"

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

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

    protected override void OnInitialized()
    {
        Text = Text ?? "fantastic";
    }
}
@page "/route-parameter-2"
@page "/route-parameter-2/{text}"

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

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

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

다른 선택적 매개 변수 값을 사용하여 동일한 구성 요소에 대한 앱 탐색을 허용하려면 OnInitialized{Async} 대신 OnParametersSet를 사용합니다. 앞의 예제를 기반으로 하여, /route-parameter-2에서 /route-parameter-2/amazing으로, 또는 /route-parameter-2/amazing에서 /route-parameter-2로 이동할 수 있어야 할 때 OnParametersSet를 사용합니다.

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

참고

경로 매개 변수는 쿼리 문자열 값에 작용하지 않습니다. 쿼리 문자열을 작업하려면 쿼리 문자열 섹션을 참조하세요 .

경로 제약 조건

경로 제약 조건은 경로 세그먼트의 형식 일치를 구성 요소에 적용합니다.

다음 예제에서 User 구성 요소의 경로는 다음과 같은 경우에만 일치합니다.

  • 요청 URL에 Id 경로 세그먼트가 있는 경우
  • Id 세그먼트가 정수(int) 형식인 경우

Pages/User.razor:

@page "/user/{Id:int}"

<h1>User Id: @Id</h1>

@code {
    [Parameter]
    public int Id { get; set; }
}
@page "/user/{Id:int}"

<h1>User Id: @Id</h1>

@code {
    [Parameter]
    public int Id { get; set; }
}
@page "/user/{Id:int}"

<h1>User Id: @Id</h1>

@code {
    [Parameter]
    public int Id { get; set; }
}
@page "/user/{Id:int}"

<h1>User Id: @Id</h1>

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

참고

경로 제약 조건은 쿼리 문자열 값에 작용하지 않습니다. 쿼리 문자열을 작업하려면 쿼리 문자열 섹션을 참조하세요 .

다음 표에 나와 있는 경로 제약 조건을 사용할 수 있습니다. 고정 문화권과 일치하는 경로 제약 조건에 대한 자세한 내용은 표 아래에 있는 경고를 참조하세요.

제약 조건 예제 일치하는 예제 고정
culture
일치
bool {active:bool} true, FALSE 아니요
datetime {dob:datetime} 2016-12-31, 2016-12-31 7:32pm
decimal {price:decimal} 49.99, -1,000.01
double {weight:double} 1.234, -1,001.01e8
float {weight:float} 1.234, -1,001.01e8
guid {id:guid} CD2C1638-1638-72D5-1638-DEADBEEF1638, {CD2C1638-1638-72D5-1638-DEADBEEF1638} 아니요
int {id:int} 123456789, -123456789
long {ticks:long} 123456789, -123456789

경고

CLR 형식(예: int 또는 DateTime)으로 변환되는 URL을 확인하는 경로 제약 조건은 항상 고정 문화권을 사용합니다. 이러한 제약 조건은 URL은 지역화될 수 없다고 가정합니다.

경로 제약 조건은 선택적 매개 변수에도 작용합니다. 다음 예제에서는 Id가 필수이지만 Option은 선택적 부울 경로 매개 변수입니다.

Pages/User.razor:

@page "/user/{Id:int}/{Option:bool?}"

<p>
    Id: @Id
</p>

<p>
    Option: @Option
</p>

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

    [Parameter]
    public bool Option { get; set; }
}

점이 포함된 URL을 사용한 라우팅

호스트된 Blazor WebAssembly 및 Blazor Server 앱의 경우 서버 쪽 기본 경로 템플릿에서 요청 URL의 마지막 세그먼트에 파일을 요청하는 점(.)이 포함되어 있다고 가정합니다. 예를 들어 관련 URL /example/some.thing은 라우터에서 some.thing라는 파일에 대한 요청으로 해석됩니다. some.thing@page 지시문을 사용하여 구성 요소에 라우팅되기 위한 것이고 some.thing이 경로 매개 변수 값인 경우 추가 구성이 없는 앱은 ‘404 - 찾을 수 없음’ 응답을 반환합니다. 점이 포함된 하나 이상의 매개 변수가 있는 경로를 사용하려면 앱에서 사용자 지정 템플릿을 사용하여 경로를 구성해야 합니다.

URL의 마지막 세그먼트에서 경로 매개 변수를 받을 수 있는 다음 Example 구성 요소를 고려합니다.

Pages/Example.razor:

@page "/example/{param?}"

<p>
    Param: @Param
</p>

@code {
    [Parameter]
    public string? Param { get; set; }
}
@page "/example/{param?}"

<p>
    Param: @Param
</p>

@code {
    [Parameter]
    public string? Param { get; set; }
}
@page "/example/{param?}"

<p>
    Param: @Param
</p>

@code {
    [Parameter]
    public string Param { get; set; }
}
@page "/example"
@page "/example/{param}"

<p>
    Param: @Param
</p>

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

호스트된 Blazor WebAssembly솔루션Server 앱이 param 경로 매개 변수에 점을 사용하여 요청을 라우팅하도록 허용하려면 Program.cs에서 선택적 매개 변수를 사용하여 대체 파일 경로 템플릿을 추가합니다.

app.MapFallbackToFile("/example/{param?}", "index.html");

param 경로 매개 변수에서 점을 사용하여 요청을 라우팅하도록 Blazor Server 앱을 구성하려면 Program.cs에서 선택적 매개 변수를 사용하여 대체 페이지 경로 템플릿을 추가합니다.

app.MapFallbackToPage("/example/{param?}", "/_Host");

호스트된 Blazor WebAssembly솔루션Server 앱이 param 경로 매개 변수에 점을 사용하여 요청을 라우팅하도록 허용하려면 Startup.Configure에서 선택적 매개 변수를 사용하여 대체 파일 경로 템플릿을 추가합니다.

Startup.cs:

endpoints.MapFallbackToFile("/example/{param?}", "index.html");

param 경로 매개 변수에서 점을 사용하여 요청을 라우팅하도록 Blazor Server 앱을 구성하려면 Startup.Configure에서 선택적 매개 변수를 사용하여 대체 페이지 경로 템플릿을 추가합니다.

Startup.cs:

endpoints.MapFallbackToPage("/example/{param?}", "/_Host");

자세한 내용은 ASP.NET Core의 라우팅을 참조하세요.

모든 경로 매개 변수 catch

여러 폴더 경계에서 경로를 캡처하는 catch-all 경로 매개 변수는 구성 요소에서 지원됩니다.

Catch-all 경로 매개 변수는 다음과 같습니다.

  • 이름이 경로 세그먼트 이름과 일치합니다. 이름 지정은 대/소문자를 구분하지 않습니다.
  • string 형식입니다. 프레임워크가 자동 캐스팅을 제공하지 않습니다.
  • URL의 끝부분에 있습니다.

Pages/CatchAll.razor:

@page "/catch-all/{*pageRoute}"

@code {
    [Parameter]
    public string? PageRoute { get; set; }
}
@page "/catch-all/{*pageRoute}"

@code {
    [Parameter]
    public string? PageRoute { get; set; }
}
@page "/catch-all/{*pageRoute}"

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

/catch-all/{*pageRoute}의 경로 템플릿이 있는 URL /catch-all/this/is/a/test의 경우 PageRoute의 값이 this/is/a/test로 설정됩니다.

캡처된 경로의 슬래시 및 세그먼트가 디코딩됩니다. /catch-all/{*pageRoute}의 경로 템플릿의 경우 /catch-all/this/is/a%2Ftest%2A URL은 this/is/a/test*를 생성합니다.

URI 및 탐색 상태 도우미

NavigationManager를 사용하여 C# 코드로 URI와 탐색을 관리할 수 있습니다. NavigationManager는 다음 표에 나와 있는 이벤트와 메서드를 제공합니다.

멤버 설명
Uri 현재 절대 URI를 가져옵니다.
BaseUri 절대 URI를 생성하기 위해 상대 URI 경로 앞에 추가할 수 있는 기본 URI(후행 슬래시 포함)를 가져옵니다. 일반적으로 BaseUri는 문서의 <base>요소(<head> 콘텐츠의 위치)에 있는 href 특성에 해당합니다.
NavigateTo 지정한 URI로 이동합니다. forceLoadtrue인 경우
  • 클라이언트 쪽 라우팅이 무시됩니다.
  • 클라이언트 쪽 라우터에서 URI를 정상적으로 처리했는지와 상관없이 브라우저에서 서버의 새 페이지를 강제로 로드합니다.
replacetrue이면 새 URI를 기록 스택에 푸시하는 대신 브라우저 기록의 현재 URI가 바뀝니다.
LocationChanged 탐색 위치가 변경된 경우에 발생하는 이벤트입니다. 자세한 내용은 위치 변경 섹션을 참조하세요.
ToAbsoluteUri 상대 URI를 절대 URI로 변환합니다.
ToBaseRelativePath 기본 URI(예: 이전에 BaseUri에서 반환된 URI)가 제공된 경우, 절대 URI를 기본 URI 접두사의 상대 URI로 변환합니다.
RegisterLocationChangingHandler 들어오는 탐색 이벤트를 처리하기 위해 처리기를 등록합니다. NavigateTo를 호출하면 항상 처리기가 호출됩니다.
GetUriWithQueryParameter 단일 매개 변수의 추가, 업데이트 또는 제거를 통해 NavigationManager.Uri를 업데이트하여 생성된 URI를 반환합니다. 자세한 내용은 쿼리 문자열 섹션을 참조하세요.
멤버 설명
Uri 현재 절대 URI를 가져옵니다.
BaseUri 절대 URI를 생성하기 위해 상대 URI 경로 앞에 추가할 수 있는 기본 URI(후행 슬래시 포함)를 가져옵니다. 일반적으로 BaseUri는 문서의 <base>요소(<head> 콘텐츠의 위치)에 있는 href 특성에 해당합니다.
NavigateTo 지정한 URI로 이동합니다. forceLoadtrue인 경우
  • 클라이언트 쪽 라우팅이 무시됩니다.
  • 클라이언트 쪽 라우터에서 URI를 정상적으로 처리했는지와 상관없이 브라우저에서 서버의 새 페이지를 강제로 로드합니다.
replacetrue이면 새 URI를 기록 스택에 푸시하는 대신 브라우저 기록의 현재 URI가 바뀝니다.
LocationChanged 탐색 위치가 변경된 경우에 발생하는 이벤트입니다. 자세한 내용은 위치 변경 섹션을 참조하세요.
ToAbsoluteUri 상대 URI를 절대 URI로 변환합니다.
ToBaseRelativePath 기본 URI(예: 이전에 BaseUri에서 반환된 URI)가 제공된 경우, 절대 URI를 기본 URI 접두사의 상대 URI로 변환합니다.
GetUriWithQueryParameter 단일 매개 변수의 추가, 업데이트 또는 제거를 통해 NavigationManager.Uri를 업데이트하여 생성된 URI를 반환합니다. 자세한 내용은 쿼리 문자열 섹션을 참조하세요.
멤버 설명
Uri 현재 절대 URI를 가져옵니다.
BaseUri 절대 URI를 생성하기 위해 상대 URI 경로 앞에 추가할 수 있는 기본 URI(후행 슬래시 포함)를 가져옵니다. 일반적으로 BaseUriwwwroot/index.html(Blazor WebAssembly) 또는 Pages/_Host.cshtml(Blazor Server)에 있는 문서 <base> 요소의 href 특성에 해당합니다.
NavigateTo 지정한 URI로 이동합니다. forceLoadtrue인 경우
  • 클라이언트 쪽 라우팅이 무시됩니다.
  • 클라이언트 쪽 라우터에서 URI를 정상적으로 처리했는지와 상관없이 브라우저에서 서버의 새 페이지를 강제로 로드합니다.
LocationChanged 탐색 위치가 변경된 경우에 발생하는 이벤트입니다.
ToAbsoluteUri 상대 URI를 절대 URI로 변환합니다.
ToBaseRelativePath 기본 URI(예: 이전에 BaseUri에서 반환된 URI)가 제공된 경우, 절대 URI를 기본 URI 접두사의 상대 URI로 변환합니다.

위치 변경

LocationChanged 이벤트의 경우 LocationChangedEventArgs는 탐색 이벤트에 대해 다음 정보를 제공합니다.

다음 구성 요소는

  • NavigateTo를 사용하여 단추를 선택하면 앱의 Counter 구성 요소(Pages/Counter.razor)로 이동합니다.
  • NavigationManager.LocationChanged를 구독하여 위치 변경 이벤트를 처리합니다.
    • HandleLocationChanged 메서드는 프레임워크에서 Dispose를 호출할 때 언후크됩니다. 메서드를 언후크하면 구성 요소의 가비지 수집이 허용됩니다.

    • 로거 구현은 단추를 선택할 때 다음 정보를 기록합니다.

      BlazorSample.Pages.Navigate: Information: URL of new location: https://localhost:{PORT}/counter

Pages/Navigate.razor:

@page "/navigate"
@using Microsoft.Extensions.Logging 
@implements IDisposable
@inject ILogger<Navigate> Logger
@inject NavigationManager Navigation

<h1>Navigate in component code example</h1>

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

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

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

    private void HandleLocationChanged(object? sender, LocationChangedEventArgs e)
    {
        Logger.LogInformation("URL of new location: {Location}", e.Location);
    }

    public void Dispose()
    {
        Navigation.LocationChanged -= HandleLocationChanged;
    }
}
@page "/navigate"
@using Microsoft.Extensions.Logging 
@implements IDisposable
@inject ILogger<Navigate> Logger
@inject NavigationManager Navigation

<h1>Navigate in component code example</h1>

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

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

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

    private void HandleLocationChanged(object? sender, LocationChangedEventArgs e)
    {
        Logger.LogInformation("URL of new location: {Location}", e.Location);
    }

    public void Dispose()
    {
        Navigation.LocationChanged -= HandleLocationChanged;
    }
}
@page "/navigate"
@using Microsoft.Extensions.Logging 
@implements IDisposable
@inject ILogger<Navigate> Logger
@inject NavigationManager Navigation

<h1>Navigate in component code example</h1>

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

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

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

    private void HandleLocationChanged(object sender, LocationChangedEventArgs e)
    {
        Logger.LogInformation("URL of new location: {Location}", e.Location);
    }

    public void Dispose()
    {
        Navigation.LocationChanged -= HandleLocationChanged;
    }
}
@page "/navigate"
@using Microsoft.Extensions.Logging 
@implements IDisposable
@inject ILogger<Navigate> Logger
@inject NavigationManager Navigation

<h1>Navigate in component code example</h1>

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

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

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

    private void HandleLocationChanged(object sender, LocationChangedEventArgs e)
    {
        Logger.LogInformation("URL of new location: {Location}", e.Location);
    }

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

구성 요소 삭제에 대한 자세한 내용은 ASP.NET Core Razor 구성 요소 수명 주기를 참조하세요.

NavigationManager는 브라우저 기록 API를 사용하여 앱에서 수행한 각 위치 변경과 관련된 탐색 기록 상태를 유지 관리합니다. 기록 상태를 유지 관리하는 것은 외부 ID 공급자를 사용하여 사용자를 인증하는 경우와 같은 외부 리디렉션 시나리오에서 특히 유용합니다. 자세한 내용은 탐색 옵션 섹션을 참조하세요.

NavigationOptionsNavigateTo에 전달하여 다음 동작을 제어합니다.

  • ForceLoad: 클라이언트 쪽 라우팅을 우회하고 URI가 클라이언트 쪽 라우터에서 처리되는지 여부에 관계없이 브라우저가 서버에서 새 페이지를 로드하도록 합니다. 기본값은 false입니다.
  • ReplaceHistoryEntry: 기록 스택의 현재 항목을 바꿉니다. false인 경우, 새 항목을 기록 스택에 추가합니다. 기본값은 false입니다.
  • HistoryEntryState: 기록 항목에 추가할 상태를 가져오거나 설정합니다.
Navigation.NavigateTo("/path", new NavigationOptions
{
    HistoryEntryState = "Navigation state"
});

위치 변경을 처리하는 동안 대상 기록 항목과 연관된 상태를 가져오는 방법에 대한 자세한 내용은 위치 변경 처리/방지 섹션을 참조하세요.

쿼리 문자열

[Parameter] 특성[SupplyParameterFromQuery] 특성을 함께 사용하여 라우팅 가능한 구성 요소의 구성 요소 매개 변수를 쿼리 문자열에서 가져올 수 있도록 지정합니다.

참고

구성 요소 매개 변수는 @page 지시문을 사용하여 라우팅 가능한 구성 요소에서만 쿼리 매개 변수 값을 받을 수 있습니다.

쿼리 문자열에서 제공되는 구성 요소 매개 변수는 다음 형식을 지원합니다.

  • bool, DateTime, decimal, double, float, Guid, int, long, string.
  • 이전 형식의 null 허용 변형
  • null 허용 여부와 상관없이 이전 형식의 배열

지정된 형식(CultureInfo.InvariantCulture)에 맞는 문화권 고정 형식이 적용됩니다.

구성 요소 매개 변수 이름과 다른 쿼리 매개 변수 이름을 사용하려면 [SupplyParameterFromQuery] 특성의 Name 속성을 지정합니다. 다음 예제에서 구성 요소 매개 변수의 C# 이름은 {COMPONENT PARAMETER NAME}입니다. {QUERY PARAMETER NAME} 자리 표시자에 다른 쿼리 매개 변수 이름이 지정됩니다.

[Parameter]
[SupplyParameterFromQuery(Name = "{QUERY PARAMETER NAME}")]
public string? {COMPONENT PARAMETER NAME} { get; set; }

URL이 /search?filter=scifi%20stars&page=3&star=LeVar%20Burton&star=Gary%20Oldman인 다음 예제에서는

  • Filter 속성이 scifi stars로 확인됩니다.
  • Page 속성이 3으로 확인됩니다.
  • Stars 배열은 star(Name = "star")라는 쿼리 매개 변수에서 채워지고 LeVar BurtonGary Oldman으로 확인됩니다.

Pages/Search.razor:

@page "/search"

<h1>Search Example</h1>

<p>Filter: @Filter</p>

<p>Page: @Page</p>

@if (Stars is not null)
{
    <p>Assignees:</p>

    <ul>
        @foreach (var name in Stars)
        {
            <li>@name</li>
        }
    </ul>
}

@code {
    [Parameter]
    [SupplyParameterFromQuery]
    public string? Filter { get; set; }

    [Parameter]
    [SupplyParameterFromQuery]
    public int? Page { get; set; }

    [Parameter]
    [SupplyParameterFromQuery(Name = "star")]
    public string[]? Stars { get; set; }
}

NavigationManager.GetUriWithQueryParameter를 사용하여 현재 URL에서 하나 이상의 쿼리 매개 변수를 추가, 변경 또는 제거합니다.

@inject NavigationManager Navigation

...

Navigation.GetUriWithQueryParameter("{NAME}", {VALUE})

앞의 예제에서

  • {NAME} 자리 표시자는 쿼리 매개 변수 이름을 지정합니다. {VALUE} 자리 표시자는 이 값을 지원되는 형식으로 지정합니다. 지원되는 형식은 이 섹션의 뒷부분에 나옵니다.
  • 단일 매개 변수를 사용하여 현재 URL과 동일한 문자열이 반환됩니다.
    • 현재 URL에 쿼리 매개 변수 이름이 없는 경우에 추가됩니다.
    • 현재 URL에 쿼리 매개 변수가 있는 경우에는 제공된 값으로 업데이트됩니다.
    • 제공된 값의 형식이 null을 허용하고 그 값이 null이면 제거됩니다.
  • 지정된 형식(CultureInfo.InvariantCulture)에 맞는 문화권 고정 형식이 적용됩니다.
  • 쿼리 매개 변수 이름과 값은 URL로 인코딩됩니다.
  • 형식의 인스턴스가 여러 개인 경우에는 이름이 일치하는 쿼리 매개 변수가 있는 모든 값이 대체됩니다.

NavigationManager.GetUriWithQueryParameters를 호출하여 여러 매개 변수가 추가, 업데이트 또는 제거된 Uri에서 생성된 URI를 만듭니다. 프레임워크는 각 값에 대해 value?.GetType()을 사용하여 각 쿼리 매개 변수의 런타임 형식을 확인하고 올바른 문화권 고정 형식을 선택합니다. 이 프레임워크는 지원되지 않는 형식에 대해 오류를 throw합니다.

@inject NavigationManager Navigation

...

Navigation.GetUriWithQueryParameters({PARAMETERS})

{PARAMETERS} 자리 표시자는 IReadOnlyDictionary<string, object>입니다.

여러 매개 변수를 추가, 업데이트 또는 제거하여 제공된 URI에서 새 URI를 생성하려면 URI 문자열을 GetUriWithQueryParameters에 전달합니다. 프레임워크는 각 값에 대해 value?.GetType()을 사용하여 각 쿼리 매개 변수의 런타임 형식을 확인하고 올바른 문화권 고정 형식을 선택합니다. 이 프레임워크는 지원되지 않는 형식에 대해 오류를 throw합니다. 지원되는 형식은 이 섹션의 뒷부분에 나옵니다.

@inject NavigationManager Navigation

...

Navigation.GetUriWithQueryParameters("{URI}", {PARAMETERS})
  • {URI} 자리 표시자는 쿼리 문자열을 포함하거나 포함하지 않는 URI입니다.
  • {PARAMETERS} 자리 표시자는 IReadOnlyDictionary<string, object>입니다.

지원되는 형식은 경로 제약 조건에 대해 지원되는 형식과 동일합니다.

  • bool
  • DateTime
  • decimal
  • double
  • float
  • Guid
  • int
  • long
  • string

지원되는 형식은 다음과 같습니다.

  • 이전 형식의 null 허용 변형
  • null 허용 여부와 상관없이 이전 형식의 배열

매개 변수가 존재하는 경우에 쿼리 매개 변수 값 바꾸기

Navigation.GetUriWithQueryParameter("full name", "Morena Baccarin")
현재 URL 생성된 URL
scheme://host/?full%20name=David%20Krumholtz&age=42 scheme://host/?full%20name=Morena%20Baccarin&age=42
scheme://host/?fUlL%20nAmE=David%20Krumholtz&AgE=42 scheme://host/?full%20name=Morena%20Baccarin&AgE=42
scheme://host/?full%20name=Jewel%20Staite&age=42&full%20name=Summer%20Glau scheme://host/?full%20name=Morena%20Baccarin&age=42&full%20name=Morena%20Baccarin
scheme://host/?full%20name=&age=42 scheme://host/?full%20name=Morena%20Baccarin&age=42
scheme://host/?full%20name= scheme://host/?full%20name=Morena%20Baccarin

매개 변수가 존재하지 않는 경우에 쿼리 매개 변수 및 값 추가

Navigation.GetUriWithQueryParameter("name", "Morena Baccarin")
현재 URL 생성된 URL
scheme://host/?age=42 scheme://host/?age=42&name=Morena%20Baccarin
scheme://host/ scheme://host/?name=Morena%20Baccarin
scheme://host/? scheme://host/?name=Morena%20Baccarin

매개 변수 값이 null인 경우에 쿼리 매개 변수 값 제거

Navigation.GetUriWithQueryParameter("full name", (string)null)
현재 URL 생성된 URL
scheme://host/?full%20name=David%20Krumholtz&age=42 scheme://host/?age=42
scheme://host/?full%20name=Sally%20Smith&age=42&full%20name=Summer%20Glau scheme://host/?age=42
scheme://host/?full%20name=Sally%20Smith&age=42&FuLl%20NaMe=Summer%20Glau scheme://host/?age=42
scheme://host/?full%20name=&age=42 scheme://host/?age=42
scheme://host/?full%20name= scheme://host/

쿼리 매개 변수 추가, 업데이트 및 제거

다음 예제에서는

  • name이 제거됩니다(있는 경우).
  • age25(int) 값으로 추가됩니다(없는 경우). 있는 경우 age25의 값으로 업데이트됩니다.
  • eye color가 추가되거나 green의 값으로 업데이트됩니다.
Navigation.GetUriWithQueryParameters(
    new Dictionary<string, object?>
    {
        ["name"] = null,
        ["age"] = (int?)25,
        ["eye color"] = "green"
    })
현재 URL 생성된 URL
scheme://host/?name=David%20Krumholtz&age=42 scheme://host/?age=25&eye%20color=green
scheme://host/?NaMe=David%20Krumholtz&AgE=42 scheme://host/?age=25&eye%20color=green
scheme://host/?name=David%20Krumholtz&age=42&keepme=true scheme://host/?age=25&keepme=true&eye%20color=green
scheme://host/?age=42&eye%20color=87 scheme://host/?age=25&eye%20color=green
scheme://host/? scheme://host/?age=25&eye%20color=green
scheme://host/ scheme://host/?age=25&eye%20color=green

열거 가능한 값 지원

다음 예제에서는

  • full name이 추가되거나 단일 값인 Morena Baccarin으로 업데이트됩니다.
  • ping 매개 변수가 추가되거나 35, 16, 87240으로 대체됩니다.
Navigation.GetUriWithQueryParameters(
    new Dictionary<string, object?>
    {
        ["full name"] = "Morena Baccarin",
        ["ping"] = new int?[] { 35, 16, null, 87, 240 }
    })
현재 URL 생성된 URL
scheme://host/?full%20name=David%20Krumholtz&ping=8&ping=300 scheme://host/?full%20name=Morena%20Baccarin&ping=35&ping=16&ping=87&ping=240
scheme://host/?ping=8&full%20name=David%20Krumholtz&ping=300 scheme://host/?ping=35&full%20name=Morena%20Baccarin&ping=16&ping=87&ping=240
scheme://host/?ping=8&ping=300&ping=50&ping=68&ping=42 scheme://host/?ping=35&ping=16&ping=87&ping=240&full%20name=Morena%20Baccarin

추가 또는 수정된 쿼리 문자열로 탐색하려면 생성된 URL을 NavigateTo에 전달합니다.

다음 예제에서는

  • GetUriWithQueryParameter를 호출하여 Morena Baccarin 값을 사용해 name 쿼리 매개 변수를 추가하거나 바꿉니다.
  • NavigateTo를 호출하여 새 URL에 대한 탐색을 트리거합니다.
Navigation.NavigateTo(
    Navigation.GetUriWithQueryParameter("name", "Morena Baccarin"));

요청의 쿼리 문자열은 NavigationManager.Uri 속성에서 가져옵니다.

@inject NavigationManager Navigation

...

var query = new Uri(Navigation.Uri).Query;

쿼리 문자열의 매개 변수를 구문 분석하는 한 가지 방법은 JS(JavaScript) interop에서 URLSearchParams를 사용하는 것입니다.

export createQueryString = (string queryString) => new URLSearchParams(queryString);

JavaScript 모듈을 사용한 JavaScript 격리에 대한 자세한 내용은 ASP.NET Core Blazor의 .NET 메서드에서 JavaScript 함수 호출을 참조하세요.

<Navigating> 콘텐츠와의 사용자 상호 작용

Router 구성 요소는 사용자에게 페이지 전환이 발생하고 있음을 나타낼 수 있습니다.

App 구성 요소(App.razor)의 맨 위에 Microsoft.AspNetCore.Components.Routing 네임스페이스에 대한 @using 지시문을 추가합니다.

@using Microsoft.AspNetCore.Components.Routing

페이지 전환 이벤트 중 표시할 태그를 사용하여 구성 요소에 <Navigating> 태그를 추가합니다. 자세한 내용은 Navigating(API 설명서)을 참조하세요.

App 구성 요소(App.razor)의 라우터 요소 내용(<Router>...</Router>)에서:

<Navigating>
    <p>Loading the requested page&hellip;</p>
</Navigating>

Navigating 속성을 사용하는 예제는 ASP.NET Core Blazor WebAssembly의 어셈블리 지연 로드를 참조하세요.

OnNavigateAsync를 사용하여 비동기 탐색 이벤트 처리

Router 구성 요소는 OnNavigateAsync 기능을 지원합니다. 사용자가 다음을 수행하면 OnNavigateAsync 처리기가 호출됩니다.

  • 브라우저에서 직접 경로로 이동하여 처음으로 경로를 방문합니다.
  • 링크 또는 NavigationManager.NavigateTo 호출을 사용하여 새 경로로 이동합니다.

App 구성 요소(App.razor)에서:

<Router AppAssembly="@typeof(App).Assembly" 
    OnNavigateAsync="@OnNavigateAsync">
    ...
</Router>

@code {
    private async Task OnNavigateAsync(NavigationContext args)
    {
        ...
    }
}
<Router AppAssembly="@typeof(Program).Assembly" 
    OnNavigateAsync="@OnNavigateAsync">
    ...
</Router>

@code {
    private async Task OnNavigateAsync(NavigationContext args)
    {
        ...
    }
}

참고

ASP.NET Core 5.0.1 릴리스 및 추가 5.x 릴리스부터 Router 구성 요소에는 @true로 설정된 PreferExactMatches 매개 변수가 포함됩니다. 자세한 내용은 ASP.NET Core 3.1에서 5.0으로 마이그레이션을 참조하세요.

OnNavigateAsync를 사용하는 예제는 ASP.NET Core Blazor WebAssembly의 어셈블리 지연 로드를 참조하세요.

Blazor Server 앱 또는 호스트된 Blazor WebAssembly 앱의 서버에서 미리 렌더링할 때 OnNavigateAsync는 ‘두 번’ 실행됩니다.

  • 첫 번째 실행은 요청된 엔드포인트 구성 요소가 처음에 정적으로 렌더링될 때입니다.
  • 두 번째 실행은 브라우저에서 엔드포인트 구성 요소를 렌더링할 때입니다.

OnNavigateAsync의 개발자 코드가 두 번 실행되지 않도록 App 구성 요소는 사용할 NavigationContextOnAfterRender{Async}(여기서 firstRender를 확인할 수 있음)에 저장할 수 있습니다. 자세한 내용은 Blazor수명 주기 문서에서JavaScript interop을 사용한 미리 렌더링를 참조하세요.

OnNavigateAsync에서의 취소 처리

OnNavigateAsync 콜백에 전달되는 NavigationContext 개체에는 새 탐색 이벤트가 발생할 때 설정되는 CancellationToken이 포함됩니다. 오래된 탐색에서 OnNavigateAsync 콜백을 계속 실행하지 않도록 이 취소 토큰이 설정된 경우 OnNavigateAsync 콜백이 throw해야 합니다.

사용자가 엔드포인트로 이동한 후 즉시 새 엔드포인트로 이동하는 경우 앱은 첫 번째 엔드포인트에 대해 OnNavigateAsync 콜백을 계속 실행해서는 안 됩니다.

다음 App 구성 요소 예제에서

  • 취소 토큰은 사용자가 /about 엔드포인트에서 벗어나면 POST를 취소할 수 있는 PostAsJsonAsync 호출로 전달됩니다.
  • 취소 토큰은 사용자가 /store 엔드포인트에서 벗어나면 제품 프리페치 작업 중에 설정됩니다.

App.razor:

@inject HttpClient Http
@inject ProductCatalog Products

<Router AppAssembly="@typeof(App).Assembly" 
    OnNavigateAsync="@OnNavigateAsync">
    ...
</Router>

@code {
    private async Task OnNavigateAsync(NavigationContext context)
    {
        if (context.Path == "/about") 
        {
            var stats = new Stats { Page = "/about" };
            await Http.PostAsJsonAsync("api/visited", stats, 
                context.CancellationToken);
        }
        else if (context.Path == "/store")
        {
            var productIds = [345, 789, 135, 689];

            foreach (var productId in productIds) 
            {
                context.CancellationToken.ThrowIfCancellationRequested();
                Products.Prefetch(productId);
            }
        }
    }
}
@inject HttpClient Http
@inject ProductCatalog Products

<Router AppAssembly="@typeof(Program).Assembly" 
    OnNavigateAsync="@OnNavigateAsync">
    ...
</Router>

@code {
    private async Task OnNavigateAsync(NavigationContext context)
    {
        if (context.Path == "/about") 
        {
            var stats = new Stats { Page = "/about" };
            await Http.PostAsJsonAsync("api/visited", stats, 
                context.CancellationToken);
        }
        else if (context.Path == "/store")
        {
            var productIds = [345, 789, 135, 689];

            foreach (var productId in productIds) 
            {
                context.CancellationToken.ThrowIfCancellationRequested();
                Products.Prefetch(productId);
            }
        }
    }
}

참고

ASP.NET Core 5.0.1 릴리스 및 추가 5.x 릴리스부터 Router 구성 요소에는 @true로 설정된 PreferExactMatches 매개 변수가 포함됩니다. 자세한 내용은 ASP.NET Core 3.1에서 5.0으로 마이그레이션을 참조하세요.

참고

NavigationContext의 취소 토큰이 취소되는 경우 throw하지 않으면 이전 탐색에서 구성 요소를 렌더링하는 것과 같은 의도하지 않은 동작이 발생할 수 있습니다.

위치 변경 처리/방지

RegisterLocationChangingHandler에서는 들어오는 탐색 이벤트를 처리하기 위해 처리기를 등록합니다. LocationChangingContext에서 제공하는 처리기의 컨텍스트에는 다음 속성이 포함됩니다.

구성 요소는 OnAfterRender 또는 OnAfterRenderAsync 메서드에 여러 위치 변경 처리기를 등록할 수 있습니다. 탐색은 전체 앱(여러 구성 요소에서)에 등록된 모든 위치 변경 처리기를 호출하고 내부 탐색은 모두 병렬로 실행합니다. NavigateTo 처리기 외에도 다음과 같이 호출됩니다.

  • 앱의 기본 경로 아래의 URL을 가리키는 링크인 내부 링크를 선택하는 경우
  • 브라우저에서 앞으로 및 뒤로 단추를 사용하여 탐색하는 경우

처리기는 앱 내의 내부 탐색에 대해서만 실행됩니다. 사용자가 다른 사이트로 이동하는 링크를 선택하거나 주소 표시줄을 다른 사이트로 수동으로 변경하는 경우에는 위치 변경 처리기가 실행되지 않습니다.

IDisposable을 구현하고 등록된 처리기를 삭제하여 등록을 취소합니다. 자세한 내용은 ASP.NET Core Razor 구성 요소 수명 주기를 참조하세요.

다음 예제에서는 위치 변경 처리기가 탐색 이벤트에 등록됩니다.

Pages/NavHandler.razor:

@page "/nav-handler"
@inject NavigationManager Navigation
@implements IDisposable

<p>
    <button @onclick="@(() => Navigation.NavigateTo("/"))">
        Home (Allowed)
    </button>
    <button @onclick="@(() => Navigation.NavigateTo("/counter"))">
        Counter (Prevented)
    </button>
</p>

@code {
    private IDisposable? registration;

    protected override void OnAfterRender(bool firstRender)
    {
        if (firstRender)
        {
            registration = 
                Navigation.RegisterLocationChangingHandler(OnLocationChanging);
        }
    }

    private ValueTask OnLocationChanging(LocationChangingContext context)
    {
        if (context.TargetLocation == "/counter")
        {
            context.PreventNavigation();
        }

        return ValueTask.CompletedTask;
    }

    public void Dispose() => registration?.Dispose();
}

내부 탐색은 비동기적으로 취소할 수 있으므로 등록된 처리기에 대한 여러 겹치는 호출이 발생할 수 있습니다. 예를 들어 탐색이 실행되기 전에 사용자가 페이지에서 뒤로 단추를 빠르게 선택하거나 여러 링크를 선택할 때 여러 처리기 호출이 발생할 수 있습니다. 다음은 비동기 탐색 논리의 요약입니다.

  • 위치 변경 처리기가 등록된 경우 모든 탐색이 처음에 되돌려진 다음 탐색이 취소되지 않으면 재생됩니다.
  • 겹치는 탐색 요청이 있으면 최신 요청은 이전 요청을 항상 취소합니다. 다음의 경우를 의미합니다.
    • 앱은 여러 개의 뒤로 및 앞으로 단추 선택을 단일 선택 영역으로 처리할 수 있습니다.
    • 탐색이 완료되기 전에 사용자가 여러 링크를 선택하면 선택한 마지막 링크에 따라 탐색이 결정됩니다.

탐색 기록 스택의 항목 및 상태를 제어하기 위해 NavigationOptionsNavigateTo로 전달하는 방법에 대한 자세한 내용은 탐색 옵션 섹션을 참조하세요.

추가 예제 코드에 대한 자세한 내용은 BasicTestAppNavigationManagerComponent를 참조하세요(dotnet/aspnetcore 참조 소스).

참고

.NET 참조 원본의 설명서 링크는 일반적으로 다음 릴리스의 .NET을 위한 현재 개발을 나타내는 리포지토리의 기본 분기를 로드합니다. 특정 릴리스를 위한 태그를 선택하려면 Switch branches or tags(분기 또는 태그 전환) 드롭다운 목록을 사용합니다. 자세한 내용은 ASP.NET Core 소스 코드(dotnet/AspNetCore.Docs #26205)의 버전 태그를 선택하는 방법을 참조하세요.

NavigationLock 구성 요소는 렌더링되는 한 탐색 이벤트를 가로채서 진행하거나 취소하기로 결정할 때까지 지정된 탐색을 효과적으로 "잠금"합니다. 탐색 차단 범위를 구성 요소의 수명으로 지정할 수 있는 경우 를 사용합니다 NavigationLock .

NavigationLock 매개 변수:

  • ConfirmExternalNavigation은 사용자에게 외부 탐색을 확인하거나 취소하라는 메시지를 표시하는 브라우저 대화 상자를 설정합니다. 기본값은 false입니다. 확인 대화 상자를 표시하려면 브라우저의 주소 표시줄에 있는 URL을 사용하여 외부 탐색을 트리거하기 전에 페이지와 초기 사용자의 상호 작용이 필요합니다. 상호 작용 요구 사항에 대한 자세한 내용은 Window: beforeunload 이벤트(MDN 문서)를 참조하세요.
  • OnBeforeInternalNavigation은 내부 탐색 이벤트의 콜백을 설정합니다.

다음은 NavLock 구성 요소에 대한 설명입니다.

Pages/NavLock.razor:

@page "/nav-lock"
@inject IJSRuntime JSRuntime
@inject NavigationManager Navigation

<NavigationLock ConfirmExternalNavigation="true" 
    OnBeforeInternalNavigation="OnBeforeInternalNavigation" />

<p>
    <button @onclick="Navigate">Navigate</button>
</p>

<p>
    <a href="https://www.microsoft.com">Microsoft homepage</a>
</p>

@code {
    private void Navigate()
    {
        Navigation.NavigateTo("/");
    }

    private async Task OnBeforeInternalNavigation(LocationChangingContext context)
    {
        var isConfirmed = await JSRuntime.InvokeAsync<bool>("confirm", 
            "Are you sure you want to navigate to the Index page?");

        if (!isConfirmed)
        {
            context.PreventNavigation();
        }
    }
}

추가 예제 코드에 대한 자세한 내용은 BasicTestAppConfigurableNavigationLock 구성 요소를 참조하세요(dotnet/aspnetcore 참조 소스).

탐색 링크를 만드는 경우 HTML 하이퍼링크 요소(<a>) 대신 NavLink 구성 요소를 사용합니다. NavLink 구성 요소는 href가 현재 URL과 일치하는지 아닌지에 따라 active CSS 클래스를 전환한다는 점을 제외하고 <a> 요소처럼 동작합니다. active 클래스는 사용자가 표시되는 탐색 링크 중에서 활성 페이지를 파악하는 데 도움이 됩니다. 현재 경로가 href와 일치하는 경우, 필요에 따라 NavLink.ActiveClass에 CSS 클래스 이름을 할당하여 렌더링된 링크에 사용자 지정 CSS 클래스를 적용합니다.

참고

NavMenu 구성 요소(NavMenu.razor)는 Blazor 프로젝트 템플릿에서 생성된 앱의 Shared 폴더에서 제공됩니다.

<NavLink> 요소의 Match 특성에 할당할 수 있는 다음 두 가지 NavLinkMatch 옵션이 있습니다.

앞의 예제에서 HomeNavLinkhref=""는 홈 URL과 일치하며 앱의 기본 경로 URL(/)에 있는 active CSS 클래스만 받습니다. 두 번째 NavLink는 사용자가 component 접두사를 포함하는 URL(예: /component/component/another-segment)을 방문할 때 active 클래스를 받습니다.

추가 NavLink 구성 요소 특성이 렌더링된 앵커 태그로 전달됩니다. 다음 예제에서 NavLink 구성 요소는 target 특성을 포함합니다.

<NavLink href="example-page" target="_blank">Example page</NavLink>

다음 HTML 태그가 렌더링됩니다.

<a href="example-page" target="_blank">Example page</a>

경고

Blazor가 자식 콘텐츠를 렌더링하는 방식 때문에 for 루프 내에서 NavLink 구성 요소를 렌더링하려면 NavLink(자식) 구성 요소 콘텐츠에서 증분 루프 변수를 사용할 경우 로컬 인덱스 변수가 필요합니다.

@for (int c = 0; c < 10; c++)
{
    var current = c;
    <li ...>
        <NavLink ... href="@c">
            <span ...></span> @current
        </NavLink>
    </li>
}

이 시나리오에서 인덱스 변수를 사용하는 것은 NavLink 구성 요소뿐 아니라 자식 콘텐츠에서 루프 변수를 사용하는 모든 자식 구성 요소의 요구 사항입니다.

또는 Enumerable.Range을 활용하여 foreach 루프를 사용할 수 있습니다.

@foreach (var c in Enumerable.Range(0,10))
{
    <li ...>
        <NavLink ... href="@c">
            <span ...></span> @c
        </NavLink>
    </li>
}

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

‘이 섹션은 Blazor Server 앱에만 적용됩니다.’

Blazor Server는 ASP.NET Core 엔드포인트 라우팅에 통합됩니다. Program.csMapBlazorHub를 사용하여 대화형 구성 요소에 대해 들어오는 연결을 허용하도록 ASP.NET Core 앱을 구성합니다.

app.UseRouting();

app.MapBlazorHub();
app.MapFallbackToPage("/_Host");

Blazor Server는 ASP.NET Core 엔드포인트 라우팅에 통합됩니다. Startup.ConfigureMapBlazorHub를 사용하여 대화형 구성 요소에 대해 들어오는 연결을 허용하도록 ASP.NET Core 앱을 구성합니다.

Startup.cs:

using Microsoft.AspNetCore.Builder;

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.UseRouting();

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

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.UseRouting();

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

일반적인 구성은 Blazor Server 앱의 서버 쪽 호스트 역할을 하는 Razor 페이지로 모든 요청을 라우팅하는 것입니다. 규칙에 따라 ‘호스트’ 페이지의 이름은 일반적으로 앱의 Pages 폴더에서 _Host.cshtml입니다.

호스트 파일에 지정된 경로는 경로 일치 시 낮은 우선순위로 작동하기 때문에 ‘대체 경로’라고 합니다. 일치하는 다른 경로가 없는 경우 대체(fallback) 경로가 사용됩니다. 이렇게 하면 앱이 Blazor Server 앱의 구성 요소 라우팅을 방해하지 않고 다른 컨트롤러와 페이지를 사용할 수 있습니다.

루트가 아닌 URL 서버 호스팅을 구성하는 MapFallbackToPage 방법에 대한 자세한 내용은 ASP.NET Core Blazor호스트 및 배포를 참조하세요.