- ASP.NET Core Blazor 路由ASP.NET Core Blazor routing
- ASP.NET Core 终结点路由集成ASP.NET Core endpoint routing integration
- 路由模板Route templates
- 在找不到内容时提供自定义内容Provide custom content when content isn't found
- 从多个程序集路由到组件Route to components from multiple assemblies
- 路由参数Route parameters
- 路由约束Route constraints
- NavLink 组件NavLink component
- URI 和导航状态帮助程序URI and navigation state helpers
ASP.NET Core Blazor 路由ASP.NET Core Blazor routing
本文内容
作者:Luke Latham
重要
Blazor WebAssembly 为预览版状态
ASP.NET Core 3.0 支持 Blazor Server。Blazor WebAssembly 在 ASP.NET Core 3.1 中为预览版。
了解如何路由请求以及如何使用 NavLink
组件在 Blazor 应用中创建导航链接。
ASP.NET Core 终结点路由集成ASP.NET Core endpoint routing integration
Blazor Server 已集成到 ASP.NET Core 终结点路由中。ASP.NET Core 应用配置为接受 Startup.Configure
中带有 MapBlazorHub
的交互式组件的传入连接:
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});
最典型的配置是将所有请求路由到 Razor 页面,该页面充当 Blazor Server 应用服务器端部分的主机。按照约定,主机页通常命名为 _Host.cshtml。主机文件中指定的路由称为回退路由,因为它在路由匹配中以较低的优先级运行。其他路由不匹配时,会考虑回退路由。这让应用能够使用其他控制器和页面,而不会干扰 Blazor Server 应用。
路由模板Route templates
Router
组件可实现到具有指定路由的每个组件的路由。Router
组件出现在 App.razor 文件中:
<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。
在运行时,RouteView
组件:
- 从
Router
接收RouteData
以及任何所需的参数。 - 通过指定参数使用指定组件的布局(或可选的默认布局)呈现该组件。
可选择使用布局类指定 DefaultLayout
参数,以用于未指定布局的组件。默认的 Blazor 模板指定 MainLayout
组件。MainLayout.razor 在模板项目的 Shared 文件夹中。有关布局的详细信息,请参阅 ASP.NET Core Blazor 布局。
可将多个路由模板应用于一个组件。以下组件响应对 /BlazorRoute
和 /DifferentBlazorRoute
的请求:
@page "/BlazorRoute"
@page "/DifferentBlazorRoute"
<h1>Blazor routing</h1>
重要
若要正确解析 URL,应用必须在其 wwwroot/index.html 文件 (Blazor WebAssembly) 或 Pages/_Host.cshtml 文件 (Blazor Server) 中包括 <base>
标记,并使用 href
属性 (<base href="/">
) 中指定的应用基路径。有关详细信息,请参阅 托管和部署 ASP.NET Core Blazor。
在找不到内容时提供自定义内容Provide custom content when content isn't found
如果找不到所请求路由的内容,则 Router
组件允许应用指定自定义内容。
在 App.razor 文件中,在 Router
组件的 NotFound
模板参数中设置自定义内容:
<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>
标记的内容可以包括任意项,例如其他交互式组件。若要将默认布局应用于 NotFound
内容,请参阅 ASP.NET Core Blazor 布局。
从多个程序集路由到组件Route to components from multiple assemblies
使用 AdditionalAssemblies
参数为 Router
组件指定搜索可路由组件时要考虑的其他程序集。除 AppAssembly
指定的程序集外,还要考虑指定的程序集。在以下示例中,Component1
是在引用的类库中定义的可路由组件。以下 AdditionalAssemblies
示例为 Component1
提供路由支持:
<Router
AppAssembly="typeof(Program).Assembly"
AdditionalAssemblies="new[] { typeof(Component1).Assembly }">
...
</Router>
路由参数Route parameters
路由器使用路由参数以相同的名称填充相应的组件参数(不区分大小写):
@page "/RouteParameter"
@page "/RouteParameter/{text}"
<h1>Blazor is @Text!</h1>
@code {
[Parameter]
public string Text { get; set; }
protected override void OnInitialized()
{
Text = Text ?? "fantastic";
}
}
不支持可选参数。上一个示例中应用了两个 @page
指令。第一个指令允许导航到没有参数的组件。第二个 @page
指令采用 {text}
路由参数,并将值赋予 Text
属性。
路由约束Route constraints
路由约束强制在路由段和组件之间进行类型匹配。
在以下示例中,到 Users
组件的路由仅在以下情况下匹配:
- 请求 URL 上存在
Id
路由段。 Id
段是整数 (int
)。
@page "/Users/{Id:int}"
<h1>The user Id is @Id!</h1>
@code {
[Parameter]
public int Id { get; set; }
}
下表中显示的路由约束可用。有关与固定区域性匹配的路由约束,请参阅表下方的警告了解详细信息。
约束 | 示例 | 匹配项示例 | 固定条件区域性匹配 |
---|---|---|---|
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 | 是 |
警告
验证 URL 的路由约束并将转换为始终使用固定区域性的 CLR 类型(例如 int
或 DateTime
)。这些约束假定 URL 不可本地化。
使用包含点的 URL 进行路由Routing with URLs that contain dots
在 Blazor Server 应用中, Host.cshtml 中的默认路由为 /
(@page "/"
)。包含点 (.
) 的请求 URL 与默认路由不匹配,因为 URL 似乎在请求文件。Blazor 应用针对不存在的静态文件返回 _404 - 未找到响应。若要使用包含点的路由,请使用以下路由模板配置 Host.cshtml_:
@page "/{**path}"
"/{**path}"
模板包括:
- 双星号 catch-all 语法 (
**
),用于捕获跨多个文件夹边界的路径,而无需编码正斜杠 (/
)。 path
路由参数名称。
备注
Razor 组件 ( .razor) 不支持 catch-all 参数语法 (/
*
)。
有关详细信息,请参阅 ASP.NET Core 中的路由。
NavLink 组件NavLink component
创建导航链接时,请使用 NavLink
组件代替 HTML 超链接元素 (<a>
)。NavLink
组件的行为方式类似于 <a>
元素,但它根据其 href
是否与当前 URL 匹配来切换 active
CSS 类。active
类可帮助用户了解所显示导航链接中的哪个页面是活动页面。
以下 NavMenu
组件创建启动导航栏,该导航栏演示如何使用 NavLink
组件:
<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>
有两个 NavLinkMatch
选项可分配给 <NavLink>
元素的 Match
属性:
NavLinkMatch.All
–NavLink
在与当前整个 URL 匹配的情况下处于活动状态。NavLinkMatch.Prefix
(默认)–NavLink
在与当前 URL 的任何前缀匹配的情况下处于活动状态。
在前面的示例中,主页 NavLink
href=""
与主页 URL 匹配,并且仅在应用的默认基路径 URL(例如,https://localhost:5001/
)处接收 active
CSS 类。当用户访问带有 MyComponent
前缀的任何 URL(例如,https://localhost:5001/MyComponent
和 https://localhost:5001/MyComponent/AnotherSegment
)时,第二个 NavLink
接收 active
类。
其他 NavLink
组件属性会传递到呈现的定位标记。在以下示例中,NavLink
组件包括 target
属性:
<NavLink href="my-page" target="_blank">My page</NavLink>
呈现以下 HTML 标记:
<a href="my-page" target="_blank" rel="noopener noreferrer">My page</a>
URI 和导航状态帮助程序URI and navigation state helpers
在 C# 代码中将 Microsoft.AspNetCore.Components.NavigationManager
与 URI 和导航配合使用。NavigationManager
提供下表所示的事件和方法。
成员 | 描述 |
---|---|
Uri | 获取当前绝对 URI。 |
BaseUri | 获取可在相对 URI 路径之前添加用于生成绝对 URI 的基 URI(带有尾部反斜杠)。通常,BaseUri 对应于 wwwroot/index.html (Blazor WebAssembly) 或 Pages/_Host.cshtml (Blazor Server) 中文档的 <base> 元素上的 href 属性。 |
NavigateTo | 导航到指定 URI。如果 forceLoad 为 true ,则:- 客户端路由会被绕过。 - 无论 URI 是否通常由客户端路由器处理,浏览器都必须从服务器加载新页面。 |
LocationChanged | 导航位置更改时触发的事件。 |
ToAbsoluteUri | 将相对 URI 转换为绝对 URI。 |
ToBaseRelativePath | 给定基 URI(例如,之前由 GetBaseUri 返回的 URI),将绝对 URI 转换为相对于基 URI 前缀的 URI。 |
选择该按钮后,以下组件导航到应用的 Counter
组件:
@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");
}
}