探索路由参数如何影响 Blazor 应用的路由

已完成

你已了解到,在 Blazor 中,可以使用 URI 的某些部分将请求路由到正确的组件。 还可以截获 URI 的其他部分,然后使用路由参数在代码中访问它们。

假设你正在建设披萨派送公司的网站,并将披萨请求路由到 Pizzas.razor 组件。 现在,你想从 URI 获取用户最喜爱的披萨,并使用它来显示有关他们可能喜欢的其他披萨的信息。

在这里,你将了解如何使用路由参数指定要在代码中处理的 URL 部分。

注意

本单元中的代码块是说明性示例。 你将在下一单元中编写自己的代码。

路由参数

在本模块的前面部分中,你已学习了如何使用用户请求的部分 URI 将请求路由到正确的组件。 你通常希望将 URI 的其他部分用作呈现的页面中的值。 例如,假设用户请求:

http://www.contoso.com/favoritepizza/hawaiian

使用 @page 指令,你已了解如何将此请求路由到组件,例如 FavoritePizza.razor 组件。 现在你要在组件中利用值“hawaiian”。 若要获取此值,可以将其声明为路由参数。

使用 @page 指令指定将作为路由参数传递给组件的 URI 部分。 在组件的代码中,你可以像获取组件参数的值一样获取路由参数的值:

@page "/FavoritePizzas/{favorite}"

<h1>Choose a Pizza</h1>

<p>Your favorite pizza is: @Favorite</p>

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

以上代码在 @page 指令中使用大括号来指定路由参数并为其命名。

备注

组件参数是从父组件发送到子组件的值。 在父组件中,以子组件标记属性的形式指定组件参数值。 路由参数的指定方式不同。 它们作为 URI 的一部分指定。 Blazor 路由器在后台截获这些值,并将其作为组件值发送到组件,因此你可以以相同的方式访问它们。 路由参数不区分大小写,将转发给同名的组件参数。

可选路由参数

在以上示例中,{favorite} 参数是必需的。 若要使路由参数可选,请使用问号:

@page "/FavoritePizzas/{favorite?}"

<h1>Choose a Pizza</h1>

<p>Your favorite pizza is: @Favorite</p>

@code {
	[Parameter]
	public string Favorite { get; set; }
	
	protected override void OnInitialized()
	{
		Favorite ??= "Fiorentina";
	}
}

为可选参数设置默认值是很好的做法。 在以上示例中,Favorite 参数的默认值在 OnInitialized 方法中设置。

备注

当用户第一次请求页面时,OnInitialized 方法运行。 如果用户使用不同的路由参数请求同一页面,则该方法不会运行。 例如,如果希望用户从 http://www.contoso.com/favoritepizza/hawaiian 转到 http://www.contoso.com/favoritepizza,请改为在 OnParametersSet() 方法中设置默认值。

路由约束

在以上示例中,请求 URI http://www.contoso.com/favoritepizza/2 的结果将是一条无意义的消息“你喜欢的披萨是:2”。 在其他情况下,这样的类型不匹配可能会导致异常,并向用户显示错误。 请考虑为路由参数指定类型:

@page "/FavoritePizza/{preferredsize:int}"

<h1>Choose a Pizza</h1>

<p>Your favorite pizza size is: @FavoriteSize inches.</p>

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

在此示例中,如果用户请求了 http://www.contoso.com/favoritepizza/margherita,则没有上述组件的匹配项。 因此,请求会路由到其他位置。 如果用户请求 http://www.contoso.com/favoritepizza/12,则会有一个路径匹配,该组件会显示消息“您最喜欢的披萨尺寸是:12英寸”。这种路由参数的一个特定类型称为“路由约束”。 可以在约束中使用其他这些类型:

约束 示例 匹配项示例
bool {vegan:bool} http://www.contoso.com/pizzas/true
datetime {birthdate:datetime} http://www.contoso.com/customers/1995-12-12
decimal {maxprice:decimal} http://www.contoso.com/pizzas/15.00
double {weight:double} http://www.contoso.com/pizzas/1.234
float {weight:float} http://www.contoso.com/pizzas/1.564
guid {pizza id:guid} http://www.contoso.com/pizzas/CD2C1638-1638-72D5-1638-DEADBEEF1638
long {totals ales:long} http://www.contoso.com/pizzas/568192454

设置捕获全部路由参数

请考虑本单元前面部分中介绍的以下组件:

@page "/FavoritePizza/{favorite}"

<h1>Choose a Pizza</h1>

<p>Your favorite pizza is: @Favorite</p>

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

现在,假设用户尝试通过请求 URI http://www.contoso.com/favoritepizza/margherita/hawaiian 来指定两个喜好。 页面将显示消息“你喜欢的披萨是:玛格丽特”,并忽略子文件夹“hawaiian”。 可以使用捕获全部路由参数来更改此行为,该参数捕获跨多个 URI 文件夹边界(正斜杠)的路径。 将星号 (*) 作为路由参数名称前缀,使路由参数捕获全部:

@page "/FavoritePizza/{*favorites}"

<h1>Choose a Pizza</h1>

<p>Your favorite pizzas are: @Favorites</p>

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

使用相同的请求 URI,页面现在会显示消息“你喜欢的披萨是:玛格丽特/夏威夷风味”。

知识检查

1.

要使用路由参数捕获 URL 中的一部分(用于定义要处理的最爱的披萨),正确的格式是什么?

2.

哪种语法通过“捕获全部参数”演示 Blazor 路由参数?