剃刀页面路由中的可选参数

剃刀页路由基于属性路由,非常强大。参数通过URL提供将任意数据传递给页面的方法。即使通过参数值是否未传递,可选参数允许URL匹配到路由。事情可以得到 如果要允许多个可选参数,则会复杂。

有两种方式可以提供参数值作为URL的一部分 - 作为路径段(例如 /yourpage/1) or as query string values (e.g. /yourpage?id=1). 查询字符串相当简单才能使用。路径段需要 配置通常通过向其提供路由模板来完成 @page 指令在剃刀内容页面中指定路由参数的名称:

@page "{id}"

您可以指定 约束 对于数据类型 the value must match:

@page "{id:int}"

And you can use the ? syntax to indicate that the parameter value is not required:

@page "{id:int?}"

This will be matched by /yourpage and yourpage/2 but not yourpage/blah (because of the type constraint). But what if you have multiple optional parameters? 让我们说你有一个可以采取开始日期或结束的报告 日期为参数,或两者,  or neither:

@page "{startdate:datetime?}/{enddate:datetime?}"

This works fine when values for both parameters are provided e.g. /report/2019-1-1/2019-12-31. Both values are bound to PageModel properties:

可选路由参数

If you provide just one value, e.g. /report/2019-1-1, it will always be bound 到第一个参数:

可选路由参数

那么你的选择是什么?在这个阶段,它有助于你开始等同起来 路由到C#方法签名。

方法重载

您可以过载C#方法,您可以在剃刀中与路由相同 Pages via the AddPageRoute method。但是,在此示例中,重载不起作用 因为两个参数都是相同的数据类型。如果您添加了一条路线 one datetime value representing the startdate, you can't add another to represent the endate value.

默认值

你可以做的是改变第一个参数,以便它是没有 更长的可选,并提供默认值:

@page "{startdate:datetime=2000-1-1}/{enddate:datetime?}"

这是一个简洁的解决方案,你可以控制网址如何 为此路线生成。这 anchor tag helper, for example, will populate the startdate with the default 如果没有提供值:

<a asp-page="/report" asp-route-enddate="2019-12-31">View Report</a>

可选路由参数

命名参数

什么时候 在C#4.0中引入了可选参数,实施也是如此 included 命名论据 作为包的一部分。如果你想跳过一个 可选参数,您可以为其之后的其他人提供值 参数列表通过将值作为参数的名称前缀。如果 Report 是一个c#方法而不是razor页面,你只会像这样调用它 providing an enddate value:

Report(enddate: new Date(2019,12,31));

您可以使用查询字符串值而不是使用查询字符串值来实现相同的方法 用于URL中传递的数据的路径段。利用这种方法,不要 provide a route template to the @page directive. Any values provided to asp-route attributes will be assigned to query string values instead:

可选路由参数

As long as your PageModel properties have SupportsGet=true applied to their BindProperty 属性,该值将绑定到正确的属性:

可选路由参数

概括

剃刀页面URL中的多个可选参数是可能导致心理块的内容之一。一旦你开始以与C#方法的参数相同的方式想象它们,解决方案要更容易掌握。