다음을 통해 공유


ASP.NET Core Blazor 라우팅 및 탐색

참고 항목

이 문서의 최신 버전은 아닙니다. 현재 릴리스는 이 문서의 .NET 8 버전을 참조 하세요.

Warning

이 버전의 ASP.NET Core는 더 이상 지원되지 않습니다. 자세한 내용은 .NET 및 .NET Core 지원 정책을 참조 하세요. 현재 릴리스는 이 문서의 .NET 8 버전을 참조 하세요.

Important

이 정보는 상업적으로 출시되기 전에 실질적으로 수정될 수 있는 시험판 제품과 관련이 있습니다. Microsoft는 여기에 제공된 정보에 대해 어떠한 명시적, 또는 묵시적인 보증을 하지 않습니다.

현재 릴리스는 이 문서의 .NET 8 버전을 참조 하세요.

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

Important

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

정적 라우팅 및 대화형 라우팅

이 섹션은 s에 Blazor Web App적용됩니다.

미리 렌더링을 사용하도록 설정Blazor하면 라우터(Router구성 요소에서 <Router> Routes.razor)는 정적 서버 쪽 렌더링(정적 SSR) 중에 구성 요소에 대한 정적 라우팅을 수행합니다. 이러한 유형의 라우팅을 정적 라우팅이라고 합니다.

대화형 렌더링 모드가 구성 요소에 Routes 할당되면 서버에서 Blazor 정적 라우팅이 있는 정적 SSR 이후 라우터가 대화형이 됩니다. 이러한 유형의 라우팅을 대화형 라우팅이라고합니다.

정적 라우터는 엔드포인트 라우팅 및 HTTP 요청 경로를 사용하여 렌더링할 구성 요소를 결정합니다. 라우터가 대화형이 되면 문서의 URL(브라우저 주소 표시줄의 URL)을 사용하여 렌더링할 구성 요소를 결정합니다. 즉, 대화형 라우터는 문서의 URL이 다른 유효한 내부 URL로 동적으로 변경될 경우 렌더링되는 구성 요소를 동적으로 변경할 수 있으며, 새 페이지 콘텐츠를 가져오는 HTTP 요청을 수행하지 않고도 변경할 수 있습니다.

또한 대화형 라우팅은 일반 페이지 요청이 있는 서버에서 새 페이지 콘텐츠가 요청되지 않으므로 미리 렌더링할 수 없습니다. 자세한 내용은 Prerender ASP.NET Core Razor 구성 요소를 참조하세요.

경로 템플릿

Router 구성 요소는 구성 요소로 라우팅할 Razor 수 있도록 하며 앱의 Routes 구성 요소(Components/Routes.razor)에 있습니다.

구성 Router 요소를 사용하면 구성 요소로 라우팅할 수 Razor 있습니다. Router 구성 요소는 구성 요소(App.razor)에서 App 사용됩니다.

@page 지시문을 포함하는 Razor 구성 요소(.razor)를 컴파일하면 생성된 구성요소 클래스에 구성 요소의 경로 템플릿을 지정하는 RouteAttribute가 제공됩니다.

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

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

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

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

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

BlazorRoute.razor:

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

<PageTitle>Routing</PageTitle>

<h1>Routing Example</h1>

<p>
    This page is reached at either <code>/blazor-route</code> or 
    <code>/different-blazor-route</code>.
</p>
@page "/blazor-route"
@page "/different-blazor-route"

<PageTitle>Routing</PageTitle>

<h1>Routing Example</h1>

<p>
    This page is reached at either <code>/blazor-route</code> or 
    <code>/different-blazor-route</code>.
</p>
@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>

Important

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

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

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

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

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

참고 항목

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

탐색 요소에 집중

FocusOnNavigate 구성 요소는 한 페이지에서 다른 페이지로 이동한 후 CSS 선택기를 기반으로 UI 포커스를 요소로 설정합니다.

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

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

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

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

구성 요소의 NotFound 매개 변수에 Router 대한 사용자 지정 콘텐츠를 설정합니다.

<Router ...>
    ...
    <NotFound>
        ...
    </NotFound>
</Router>

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

Important

Blazor Web App는 매개 변수(<NotFound>...</NotFound>태그)를 사용하지 NotFound 않지만 프레임워크의 호환성이 손상되지 않도록 이전 버전과의 호환성을 위해 매개 변수가 지원됩니다. 서버 쪽 ASP.NET Core 미들웨어 파이프라인은 서버에서 요청을 처리합니다. 서버 쪽 기술을 사용하여 잘못된 요청을 처리합니다. 자세한 내용은 ASP.NET Core Blazor 렌더링 모드를 참조하세요.

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

이 섹션은 s에 Blazor Web App적용됩니다.

Router 구성 요소의 AdditionalAssemblies 매개 변수 및 엔드포인트 규칙 작성기를 AddAdditionalAssemblies 사용하여 추가 어셈블리에서 라우팅 가능한 구성 요소를 검색합니다. 다음 하위 섹션에서는 각 API를 사용하는 시기와 방법을 설명합니다.

정적 라우팅

정적 SSR(서버 쪽 렌더링)을 위한 추가 어셈블리에서 라우팅 가능한 구성 요소를 검색하려면 나중에 라우터가 대화형 렌더링을 위해 대화형으로 설정되더라도 어셈블리를 프레임워크에 Blazor 공개해야 합니다. AddAdditionalAssemblies 서버 프로젝트의 Program 파일에 연결된 추가 어셈블리를 사용하여 MapRazorComponents 메서드를 호출합니다.

다음 예제에서는 프로젝트의 _Imports.razor 파일을 사용하여 프로젝트 어셈블리에 라우팅 가능한 구성 요소를 BlazorSample.Client 포함합니다.

app.MapRazorComponents<App>()
    .AddAdditionalAssemblies(typeof(BlazorSample.Client._Imports).Assembly);

참고 항목

위의 지침은 구성 요소 클래스 라이브러리 시나리오에도 적용됩니다. 클래스 라이브러리 및 정적 SSR에 대한 추가 중요한 지침은 정적 서버 쪽 렌더링(정적 SSR)이 있는 ASP.NET Core Razor 클래스 라이브러리(RCL)에서 찾을 수 있습니다.

대화형 라우팅

서버에서 정적 SSR 및 정적 라우팅 후에 라우터를 대화형으로 만드는 Blazor 구성 요소(Routes.razor)에 대화형 렌더링 모드를 할당 Routes 할 수 있습니다. 예를 들어 <Routes @rendermode="InteractiveServer" /> 대화형 서버 쪽 렌더링(대화형 SSR)을 구성 요소에 Routes 할당합니다. Router 구성 요소는 구성 요소에서 대화형 SSR(대화형 서버 쪽 렌더링)을 Routes 상속합니다. 라우터는 서버에서 정적 라우팅 후 대화형이 됩니다.

대화형 라우팅에 대한 내부 탐색에는 서버에서 새 페이지 콘텐츠를 요청하는 작업이 포함되지 않습니다. 따라서 내부 페이지 요청에 대해 미리 렌더링이 발생하지 않습니다. 자세한 내용은 Prerender ASP.NET Core Razor 구성 요소를 참조하세요.

Routes 구성 요소가 서버 프로젝트에 AdditionalAssemblies 정의된 경우 구성 요소의 Router 매개 변수에 프로젝트의 어셈블리가 .Client 포함되어야 합니다. 이렇게 하면 대화형으로 렌더링될 때 라우터가 올바르게 작동할 수 있습니다.

다음 예제 Routes 에서 구성 요소는 서버 프로젝트에 있으며 _Imports.razor 프로젝트의 파일 BlazorSample.Client 은 라우팅 가능한 구성 요소를 검색할 어셈블리를 나타냅니다.

<Router
    AppAssembly="..."
    AdditionalAssemblies="new[] { typeof(BlazorSample.Client._Imports).Assembly }">
    ...
</Router>

AppAssembly에 지정된 어셈블리 외에도 추가 어셈블리가 검색됩니다.

참고 항목

위의 지침은 구성 요소 클래스 라이브러리 시나리오에도 적용됩니다.

또는 라우팅 가능한 구성 요소는 전역 Interactive WebAssembly 또는 자동 렌더링이 적용된 프로젝트에만 존재 .Client 하며 Routes 구성 요소는 서버 프로젝트가 아닌 프로젝트에 정의됩니다 .Client . 이 경우 라우팅 가능한 구성 요소가 있는 외부 어셈블리가 없으므로 값을 지정할 AdditionalAssemblies필요가 없습니다.

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

Router 구성 요소의 AdditionalAssemblies 매개 변수 및 엔드포인트 규칙 작성기를 AddAdditionalAssemblies 사용하여 추가 어셈블리에서 라우팅 가능한 구성 요소를 검색합니다.

다음 예제 Component1 에서는 참조된 구성 요소 클래스 라이브러리에 정의된 라우팅 가능한 구성 요소입니다ComponentLibrary.

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

AppAssembly에 지정된 어셈블리 외에도 추가 어셈블리가 검색됩니다.

경로 매개 변수

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

RouteParameter1.razor:

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

<PageTitle>Route Parameter 1</PageTitle>

<h1>Route Parameter Example 1</h1>

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

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

<PageTitle>Route Parameter 1</PageTitle>

<h1>Route Parameter Example 1</h1>

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

@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; }
}
@page "/route-parameter-1/{text}"

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

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

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

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

RouteParameter2.razor:

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

<PageTitle>Route Parameter 2</PageTitle>

<h1>Route Parameter Example 2</h1>

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

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

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

<PageTitle>Route Parameter 2</PageTitle>

<h1>Route Parameter Example 2</h1>

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

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

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

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

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

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

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

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

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

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

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

    protected override void OnParametersSet()
    {
        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 OnParametersSet()
    {
        Text = Text ?? "fantastic";
    }
}

수명 주기 메서드 대신 OnParametersSet{Async} 수명 주기 메서드를 사용하는 경우 사용자가 동일한 구성 요소 내에서 탐색하는 fantastic 경우 속성의 Text 기본 할당이 발생하지 않습니다.OnInitialized{Async} 예를 들어 이 상황은 사용자가 .로 /route-parameter-2/amazing /route-parameter-2이동할 때 발생합니다. 구성 요소 인스턴스가 유지되고 새 매개 변수를 수락하면 메서드가 OnInitialized 다시 호출되지 않습니다.

참고 항목

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

경로 제약 조건

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

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

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

User.razor:

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

<PageTitle>User</PageTitle>

<h1>User Example</h1>

<p>User Id: @Id</p>

@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} 00001111-aaaa-2222-bbbb-3333cccc4444, {00001111-aaaa-2222-bbbb-3333cccc4444} 아니요
int {id:int} 123456789, -123456789
long {ticks:long} 123456789, -123456789
nonfile {parameter:nonfile} Not BlazorSample.styles.css, not favicon.ico

Warning

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

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

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; }
}

경로 매개 변수에서 파일 캡처 방지

다음 경로 템플릿은 선택적 경로 매개 변수(Optional)에서 실수로 정적 자산 경로를 캡처합니다. 예를 들어 앱의 스타일시트(.styles.css)가 캡처되어 앱의 스타일이 중단됩니다.

@page "/{optional?}"

...

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

경로 매개 변수를 파일 이외의 경로를 캡처하도록 제한하려면 경로 템플릿에서 :nonfile 제약 조건을 사용합니다.

@page "/{optional:nonfile?}"

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

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

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

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된 솔루션의 앱이 경로 매개 변수에 점을 사용하여 요청을 라우팅하도록 허용하려면 파일의 param 선택적 매개 변수를 사용하여 대체 파일 경로 템플릿을 Program 추가합니다. Server

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

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

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

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

호스트된 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의 끝부분에 있습니다.

CatchAll.razor:

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

<PageTitle>Catch All</PageTitle>

<h1>Catch All Parameters Example</h1>

<p>Add some URI segments to the route and request the page again.</p>

<p>
    PageRoute: @PageRoute
</p>

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

<PageTitle>Catch All</PageTitle>

<h1>Catch All Parameters Example</h1>

<p>Add some URI segments to the route and request the page again.</p>

<p>
    PageRoute: @PageRoute
</p>

@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; }
}
@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로 이동합니다. forceLoadfalse인 경우
  • 그리고 향상된 탐색은 현재 URL에서 사용할 수 있습니다. Blazor'의 향상된 탐색이 활성화됩니다.
  • 그렇지 않으면 Blazor 요청된 URL에 대한 전체 페이지 다시 로드를 수행합니다.
forceLoadtrue인 경우
  • 클라이언트 쪽 라우팅이 무시됩니다.
  • URI가 클라이언트 쪽 대화형 라우터에서 일반적으로 처리되는지 여부에 관계없이 브라우저는 서버에서 새 페이지를 로드해야 합니다.

자세한 내용은 향상된 탐색 및 양식 처리 섹션을 참조 하세요 .

replacetrue이면 새 URI를 기록 스택에 푸시하는 대신 브라우저 기록의 현재 URI가 바뀝니다.

LocationChanged 탐색 위치가 변경된 경우에 발생하는 이벤트입니다. 자세한 내용은 위치 변경 섹션을 참조하세요.
ToAbsoluteUri 상대 URI를 절대 URI로 변환합니다.
ToBaseRelativePath 앱의 기본 URI에 따라 기본 URI 접두사를 기준으로 절대 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에 따라 기본 URI 접두사를 기준으로 절대 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에 따라 기본 URI 접두사를 기준으로 절대 URI를 URI로 변환합니다. 예를 들어 기본 URI 접 두사 섹션을 기준으로 URI 생성 섹션을 참조하세요.
GetUriWithQueryParameter 단일 매개 변수의 추가, 업데이트 또는 제거를 통해 NavigationManager.Uri를 업데이트하여 생성된 URI를 반환합니다. 자세한 내용은 쿼리 문자열 섹션을 참조하세요.
멤버 설명
Uri 현재 절대 URI를 가져옵니다.
BaseUri 절대 URI를 생성하기 위해 상대 URI 경로 앞에 추가할 수 있는 기본 URI(후행 슬래시 포함)를 가져옵니다. 일반적으로 BaseUri는 문서의 <base>요소(<head> 콘텐츠의 위치)에 있는 href 특성에 해당합니다.
NavigateTo 지정한 URI로 이동합니다. forceLoadtrue인 경우
  • 클라이언트 쪽 라우팅이 무시됩니다.
  • 클라이언트 쪽 라우터에서 URI를 정상적으로 처리했는지와 상관없이 브라우저에서 서버의 새 페이지를 강제로 로드합니다.
LocationChanged 탐색 위치가 변경된 경우에 발생하는 이벤트입니다.
ToAbsoluteUri 상대 URI를 절대 URI로 변환합니다.
ToBaseRelativePath 앱의 기본 URI에 따라 기본 URI 접두사를 기준으로 절대 URI를 URI로 변환합니다. 예를 들어 기본 URI 접 두사 섹션을 기준으로 URI 생성 섹션을 참조하세요.

위치 변경

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

다음 구성 요소는

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

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

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

Navigate.razor:

@page "/navigate"
@implements IDisposable
@inject ILogger<Navigate> Logger
@inject NavigationManager Navigation

<PageTitle>Navigate</PageTitle>

<h1>Navigate 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"
@implements IDisposable
@inject ILogger<Navigate> Logger
@inject NavigationManager Navigation

<PageTitle>Navigate</PageTitle>

<h1>Navigate 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;
    }
}
@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 구성 요소 수명 주기를 참조하세요.

향상된 탐색 및 양식 처리

이 섹션은 s에 Blazor Web App적용됩니다.

Blazor Web Apps는 페이지 탐색 및 양식 처리 요청에 대한 두 가지 유형의 라우팅을 수행할 수 있습니다.

  • 일반 탐색(문서 간 탐색): 요청 URL에 대해 전체 페이지 다시 로드가 트리거됩니다.
  • 향상된 탐색(동일한 문서 탐색): Blazor 요청을 가로채서 대신 요청을 수행합니다 fetch . Blazor 그런 다음, 응답 콘텐츠를 페이지의 DOM에 패치합니다. Blazor'의 향상된 탐색 및 양식 처리는 전체 페이지 다시 로드의 필요성을 방지하고 페이지 상태를 더 많이 유지하므로 일반적으로 페이지에서 사용자의 스크롤 위치를 잃지 않고 페이지가 더 빠르게 로드됩니다.

다음과 같은 경우 향상된 탐색을 사용할 수 있습니다.

  • Blazor Web App 스크립트(blazor.web.js)는 스크립트() 또는 Blazor WebAssembly 스크립트blazor.webassembly.js(blazor.server.js)가 아니라 Blazor Server 사용됩니다.
  • 이 기능은 명시적으로 사용하지 않도록 설정되지 않았습니다.
  • 대상 URL은 내부 기본 URI 공간(앱의 기본 경로) 내에 있습니다.

서버 쪽 라우팅 및 향상된 탐색을 사용하는 경우 위치 변경 처리기는 대화형 런타임에서 시작된 프로그래밍 방식 탐색에 대해서만 호출됩니다. 이후 릴리스에서는 링크 팔로우와 같은 추가 유형의 탐색이 위치 변경 처리기를 호출할 수도 있습니다.

향상된 탐색이 LocationChanged 발생하면 대화형 서버 및 WebAssembly 런타임에 등록된 이벤트 처리기가 일반적으로 호출됩니다. 위치 변경 처리기가 향상된 탐색을 가로채지 못할 수 있는 경우가 있습니다. 예를 들어 사용자가 대화형 런타임을 사용할 수 있게 되기 전에 다른 페이지로 전환할 수 있습니다. 따라서 처리기 실행이 보장되지 않으므로 앱 논리가 위치 변경 처리기를 호출하는 데 의존하지 않는 것이 중요합니다.

호출 NavigateTo할 때:

  • false이 경우 forceLoad 기본값은 다음과 같습니다.
    • 그리고 향상된 탐색은 현재 URL에서 사용할 수 있습니다. Blazor'의 향상된 탐색이 활성화됩니다.
    • 그렇지 않으면 Blazor 요청된 URL에 대한 전체 페이지 다시 로드를 수행합니다.
  • true경우 forceLoad : Blazor 향상된 탐색을 사용할 수 있는지 여부에 관계없이 요청된 URL에 대해 전체 페이지 다시 로드를 수행합니다.

사용 가능한 경우 항상 향상된 탐색을 수행하는 호출 NavigationManager.Refresh(bool forceLoad = false)을 통해 현재 페이지를 새로 고칠 수 있습니다. 향상된 탐색을 사용할 수 Blazor 없는 경우 전체 페이지 다시 로드를 수행합니다.

Navigation.Refresh();

향상된 탐색을 forceLoad 사용할 수 있는 경우에도 전체 페이지 다시 로드가 항상 수행되도록 매개 변수에 전달 true 합니다.

Navigation.Refresh(true);

향상된 탐색은 기본적으로 사용하도록 설정되지만 HTML 특성을 사용하여 data-enhance-nav 계층적으로 그리고 링크별로 제어할 수 있습니다.

다음 예제에서는 향상된 탐색을 사용하지 않도록 설정합니다.

<a href="redirect" data-enhance-nav="false">
    GET without enhanced navigation
</a>
<ul data-enhance-nav="false">
    <li>
        <a href="redirect">GET without enhanced navigation</a>
    </li>
    <li>
        <a href="redirect-2">GET without enhanced navigation</a>
    </li>
</ul>

대상이 비 엔드Blazor 포인트인 경우 향상된 탐색이 적용되지 않으며 클라이언트 쪽 JavaScript가 전체 페이지 로드로 다시 시도합니다. 이렇게 하면 기존 페이지에 패치를 적용해서는 안 되는 외부 페이지에 대한 프레임워크의 혼동이 발생하지 않습니다.

향상된 양식 처리를 사용하도록 설정하려면 양식에 Enhance 매개 변수 EditForm 를 추가하거나 data-enhance HTML 양식(<form>)에 특성을 추가합니다.

<EditForm ... Enhance ...>
    ...
</EditForm>
<form ... data-enhance ...>
    ...
</form>

향상된 양식 처리는 계층 구조가 아니며 자식 양식으로 전달되지 않습니다.

지원되지 않음: 양식의 상위 요소에 대해 향상된 탐색을 설정하여 양식에 대해 향상된 탐색을 사용하도록 설정할 수 없습니다.

<div ... data-enhance ...>
    <form ...>
        <!-- NOT enhanced -->
    </form>
</div>

향상된 양식 게시물은 엔드포인트에서 Blazor 만 작동합니다. 향상된 양식을 비 엔드Blazor 포인트에 게시하면 오류가 발생합니다.

향상된 탐색을 사용하지 않도록 설정하려면 다음을 수행합니다.

  • EditForm경우 폼 요소에서 매개 변수를 제거 Enhance 하거나 다음Enhance="false"으로 false설정합니다.
  • HTML<form>의 경우 양식 요소에서 특성을 제거 data-enhance 하거나 다음data-enhance="false"으로 false설정합니다.

Blazor업데이트된 콘텐츠가 서버 렌더링의 일부가 아닌 경우 향상된 탐색 및 양식 전달을 통해 DOM에 대한 동적 변경 내용을 실행 취소할 수 있습니다. 요소의 콘텐츠를 유지하려면 특성을 사용합니다 data-permanent .

다음 예제에서는 페이지가 로드되면 요소의 <div> 콘텐츠가 스크립트에 의해 동적으로 업데이트됩니다.

<div data-permanent>
    ...
</div>

클라이언트에서 시작되면 Blazor 이벤트를 사용하여 enhancedload 향상된 페이지 업데이트를 수신 대기할 수 있습니다. 이렇게 하면 향상된 페이지 업데이트로 실행 취소되었을 수 있는 변경 내용을 DOM에 다시 적용할 수 있습니다.

Blazor.addEventListener('enhancedload', () => console.log('Enhanced update!'));

향상된 탐색 및 양식 처리를 전역적으로 사용하지 않도록 설정하려면 ASP.NET Core Blazor 시작을 참조하세요.

정적 서버 쪽 렌더링(정적 SSR)을 사용하여 향상된 탐색은 JavaScript를 로드할 때 특별히 주의해야 합니다. 자세한 내용은 정적 서버 쪽 렌더링(정적 SSR)이 있는 ASP.NET Core Blazor JavaScript를 참조하세요.

기본 URI 접두사를 기준으로 URI 생성

앱의 기본 URI ToBaseRelativePath 에 따라 기본 URI 접두사를 기준으로 절대 URI를 URI로 변환합니다.

다음 예시를 참조하세요.

try
{
    baseRelativePath = Navigation.ToBaseRelativePath(inputURI);
}
catch (ArgumentException ex)
{
    ...
}

앱의 기본 URI인 https://localhost:8000경우 다음 결과를 얻습니다.

  • 의 결과를 전달 https://localhost:8000/segment 합니다 baseRelativePath segment.inputURI
  • 의 결과를 전달 https://localhost:8000/segment1/segment2 합니다 baseRelativePath segment1/segment2.inputURI

앱의 기본 URI가 기본 URI inputURI와 일치하지 않으면 throw ArgumentException 됩니다.

inputURI 다음 예외에서 결과를 전달 https://localhost:8001/segment 합니다.

System.ArgumentException: 'The URI 'https://localhost:8001/segment' is not contained by the base URI 'https://localhost:8000/'.'

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

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

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

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

쿼리 문자열

[SupplyParameterFromQuery] 특성을 사용하여 구성 요소 매개 변수가 쿼리 문자열에서 제공되도록 지정합니다.

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

참고 항목

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

하향식 정보 흐름을 전복하지 않고 프레임워크와 앱에서 매개 변수 처리 순서를 명확하게 하기 위해 라우팅 가능한 구성 요소만 쿼리 매개 변수를 직접 받습니다. 이 디자인은 특정 매개 변수 처리 순서로 작성된 앱 코드의 미묘한 버그를 방지합니다. 라우팅할 수 없는 구성 요소에 쿼리 매개 변수 값을 전달하기 위해 사용자 지정 연계 매개 변수를 정의하거나 일반 구성 요소 매개 변수에 직접 할당할 수 있습니다.

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

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

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

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

구성 요소 매개 변수 속성()와 달리 속성은 private public.[Parameter][SupplyParameterFromQuery]

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

구성 요소 매개 변수 속성()[Parameter][SupplyParameterFromQuery]처럼 속성은 항상 public .NET 6/7의 속성입니다. .NET 8 이상 [SupplyParameterFromQuery] 에서는 속성을 표시 public 하거나 private.

[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으로 확인됩니다.

참고 항목

다음 라우팅 가능한 페이지 구성 요소의 쿼리 문자열 매개 변수는 지시문 없이 @page 라우팅할 수 없는 구성 요소에서도 작동합니다(예Search.razor: 다른 구성 요소에서 사용되는 공유 Search 구성 요소의 경우).

Search.razor:

@page "/search"

<h1>Search Example</h1>

<p>Filter: @Filter</p>

<p>Page: @Page</p>

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

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

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

    [SupplyParameterFromQuery]
    private int? Page { get; set; }

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

Search.razor:

@page "/search"

<h1>Search Example</h1>

<p>Filter: @Filter</p>

<p>Page: @Page</p>

@if (Stars is not null)
{
    <p>Stars:</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; }
}

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

@inject NavigationManager Navigation

...

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

앞의 예제에서

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

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 허용 여부와 상관없이 이전 형식의 배열

Warning

기본적으로 사용하도록 설정된 압축을 사용하면 신뢰할 수 없는 원본에서 데이터를 렌더링하는 보안(인증/권한이 부여된) 대화형 서버 쪽 구성 요소를 만들지 마세요. 신뢰할 수 없는 원본에는 경로 매개 변수, 쿼리 문자열, interop의 데이터 JS 및 타사 사용자가 제어할 수 있는 기타 데이터 원본(데이터베이스, 외부 서비스)이 포함됩니다. 자세한 내용은 ASP.NET Core BlazorSignalR 대화형 서버 쪽 렌더링에 대한 ASP.NET Core Blazor 지침위협 완화 지침을 참조하세요.

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

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 함수 호출을 참조하세요.

명명된 요소에 대한 해시된 라우팅

요소에 대한 해시된(#) 참조와 함께 다음 방법을 사용하여 명명된 요소로 이동합니다. 구성 요소 내의 요소에 대한 경로 및 외부 구성 요소의 요소에 대한 경로는 루트 상대 경로를 사용합니다. 선행 슬래시(/)는 선택 사항입니다.

다음 방법 각각에 대한 예제에서는 구성 요소의 요소가 있는 id targetElement 요소에 대한 탐색을 Counter 보여 줍니다.

  • 다음을 사용하는 hrefAnchor 요소(<a>)

    <a href="/counter#targetElement">
    
  • NavLink구성 요소:href

    <NavLink href="/counter#targetElement">
    
  • NavigationManager.NavigateTo 상대 URL 전달:

    Navigation.NavigateTo("/counter#targetElement");
    

다음 예제에서는 구성 요소 내의 명명된 H2 제목 및 외부 구성 요소에 대한 해시된 라우팅을 보여 줍니다.

Home (Home.razor) 및 Counter (Counter.razor) 구성 요소에서 다음 태그를 기존 구성 요소 태그의 맨 아래에 배치하여 탐색 대상으로 사용합니다. 브라우저 <div> 스크롤 동작을 보여 주는 인공 세로 공간을 만듭니다.

<div class="border border-info rounded bg-info" style="height:500px"></div>

<h2 id="targetElement">Target H2 heading</h2>
<p>Content!</p>

앱에 다음 HashedRouting 구성 요소를 추가합니다.

HashedRouting.razor:

@page "/hashed-routing"
@inject NavigationManager Navigation

<PageTitle>Hashed routing</PageTitle>

<h1>Hashed routing to named elements</h1>

<ul>
    <li>
        <a href="/hashed-routing#targetElement">
            Anchor in this component
        </a>
    </li>
    <li>
        <a href="/#targetElement">
            Anchor to the <code>Home</code> component
        </a>
    </li>
    <li>
        <a href="/counter#targetElement">
            Anchor to the <code>Counter</code> component
        </a>
    </li>
    <li>
        <NavLink href="/hashed-routing#targetElement">
            Use a `NavLink` component in this component
        </NavLink>
    </li>
    <li>
        <button @onclick="NavigateToElement">
            Navigate with <code>NavigationManager</code> to the 
            <code>Counter</code> component
        </button>
    </li>
</ul>

<div class="border border-info rounded bg-info" style="height:500px"></div>

<h2 id="targetElement">Target H2 heading</h2>
<p>Content!</p>

@code {
    private void NavigateToElement()
    {
        Navigation.NavigateTo("/counter#targetElement");
    }
}

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

앱에서 어셈블리를 지연 로드하는 동안 또는 서버 쪽 앱 Router 에 Blazor WebAssembly 대한 느린 네트워크 연결 Blazor 과 같이 탐색하는 동안 상당한 지연이 발생하는 경우 구성 요소는 사용자에게 페이지 전환이 발생함을 나타낼 수 있습니다.

구성 요소를 지정 Router 하는 구성 요소의 맨 위에 네임스페이스에 대한 Microsoft.AspNetCore.Components.Routing 지시문을 추가 @using 합니다.

@using Microsoft.AspNetCore.Components.Routing

페이지 전환 이벤트 중에 표시할 Navigating 콘텐츠를 매개 변수에 제공합니다.

라우터 요소(<Router>...</Router>) 콘텐츠에서:

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

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

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

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

  • 브라우저에서 직접 경로로 이동하여 처음으로 경로를 방문합니다.
  • 링크 또는 NavigationManager.NavigateTo 호출을 사용하여 새 경로로 이동합니다.
<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)
    {
        ...
    }
}

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

서버 OnNavigateAsync 에서 미리 렌더링하는 경우 다음 두 번 실행됩니다.

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

개발자 코드가 두 번 Routes 실행되지 않도록 하기 위해 구성 요소는 수명 주기 메서드OnAfterRender{Async} 사용할 수 있도록 저장할 NavigationContext 수 있습니다. 여기서 firstRender 확인할 수 OnNavigateAsync 있습니다. 자세한 내용은 JavaScript interop로 미리 렌더링을 참조하세요.

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

OnNavigateAsync에서의 취소 처리

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

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

다음 예제에서

  • 취소 토큰은 사용자가 /about 엔드포인트에서 벗어나면 POST를 취소할 수 있는 PostAsJsonAsync 호출로 전달됩니다.
  • 취소 토큰은 사용자가 /store 엔드포인트에서 벗어나면 제품 프리페치 작업 중에 설정됩니다.
@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 = new[] { 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 = new[] { 345, 789, 135, 689 };

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

참고 항목

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

위치 변경 처리/방지

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

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

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

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

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

Important

위치 변경을 처리할 때 JavaScript(JS) interop을 통해 DOM 정리 작업을 실행하지 마세요. 클라이언트에서 MutationObserver JS 패턴을 사용합니다. 자세한 내용은 ASP.NET Core Blazor JavaScript 상호 운용성(JS)을 참조하세요.

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

NavHandler.razor:

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

<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 구성 요소에 대한 설명입니다.

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 root page?");

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

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

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

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

앞의 예제 HomeNavLink href="" 에서 URL과 일치 home 하고 앱의 기본 기본 경로(/)에서만 CSS 클래스를 받 active 습니다. 두 번째 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>

Warning

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

@for (int c = 1; c < 4; c++)
{
    var ct = c;
    <li ...>
        <NavLink ...>
            <span ...></span> Product #@ct
        </NavLink>
    </li>
}

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

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

@foreach (var c in Enumerable.Range(1, 3))
{
    <li ...>
        <NavLink ...>
            <span ...></span> Product #@c
        </NavLink>
    </li>
}

NavLink 구성 요소 항목은 리플렉션을 통해 앱의 구성 요소에서 동적으로 만들 수 있습니다. 다음 예제에서는 추가 사용자 지정에 대한 일반적인 방법을 보여 줍니다.

다음 데모에서는 앱의 구성 요소에 일관된 표준 명명 규칙이 사용됩니다.

  • 예를 들어 Pages/ProductDetail.razor라우팅 가능한 구성 요소 파일 이름은 파스칼 대/소문자†를 사용합니다.
  • 라우팅 가능한 구성 요소 파일 경로는 kebab 케이스의 URL과 일치하며 구성 요소의 경로 템플릿에 있는 단어 사이에 하이픈이 표시됩니다. 예를 들어 /product-detail(@page "/product-detail")이라는 경로 템플릿을 사용하는 ProductDetail 구성 요소는 브라우저의 상대 URL /product-detail에서 요청됩니다.

†파스칼식 대/소문자(카멜 대문자)는 공백 및 문장 부호가 없고 첫 단어를 포함하여 각 단어의 첫 글자를 대문자로 표시하는 명명 규칙입니다.
_Kebab 대/소문자 구분선은 소문자와 단어 사이에 대시를 사용하는 공백과 문장 부호가 없는 명명 규칙입니다.

Razor 기본 Home 페이지 NavLink 아래의 구성 요소(NavMenu.razor)의 NavMenu 태그에서 구성 요소는 컬렉션에서 추가됩니다.

<div class="nav-scrollable" 
    onclick="document.querySelector('.navbar-toggler').click()">
    <nav class="flex-column">
        <div class="nav-item px-3">
            <NavLink class="nav-link" href="" Match="NavLinkMatch.All">
                <span class="bi bi-house-door-fill-nav-menu" 
                    aria-hidden="true"></span> Home
            </NavLink>
        </div>

+       @foreach (var name in GetRoutableComponents())
+       {
+           <div class="nav-item px-3">
+               <NavLink class="nav-link" 
+                       href="@Regex.Replace(name, @"(\B[A-Z]|\d+)", "-$1").ToLower()">
+                   @Regex.Replace(name, @"(\B[A-Z]|\d+)", " $1")
+               </NavLink>
+           </div>
+       }

    </nav>
</div>

GetRoutableComponents 블록의 @code 메서드:

public IEnumerable<string> GetRoutableComponents() => 
    Assembly.GetExecutingAssembly()
        .ExportedTypes
        .Where(t => t.IsSubclassOf(typeof(ComponentBase)))
        .Where(c => c.GetCustomAttributes(inherit: true)
                     .OfType<RouteAttribute>()
                     .Any())
        .Where(c => c.Name != "Home" && c.Name != "Error")
        .OrderBy(o => o.Name)
        .Select(c => c.Name);

앞의 예제에서는 렌더링된 구성 요소 목록에 다음 페이지를 포함하지 않습니다.

  • Home 페이지: 페이지가 목록의 맨 위에 표시되고 매개 변수를 설정 Match 해야 하므로 자동으로 생성된 링크와 별도로 나열됩니다.
  • Error 페이지: 오류 페이지는 프레임워크에서만 탐색되며 나열하면 안 됩니다.

로컬로 실행할 수 있는 샘플 앱의 이전 코드 예제를 보려면 또는 샘플 앱을 가져옵니다Blazor Web App.Blazor WebAssembly

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

이 섹션은 회로를 Blazor Web App통해 작동하는 S에 적용됩니다.

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

A Blazor Web App 는 ASP.NET 핵심 엔드포인트 라우팅에 통합됩니다. ASP.NET Core 앱은 파일에 있는 대화형 구성 요소에 대해 들어오는 연결을 허용하도록 구성됩니다 MapRazorComponents Program . 기본 루트 구성 요소(로드된 첫 번째 구성 요소)는 구성 요소(App.razor)입니다App.

app.MapRazorComponents<App>();

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

app.UseRouting();

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

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

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

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

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