MVC 路由定义具有 URL 段。您的路线如下所示:
default.aspx/{page}/{pagetype}
这意味着类似的请求default.aspx/order
应该在路由解析期间填充page
值,因为它是作为 URL 段提供的。这并不意味着page
以后当模型绑定发生并且您的控制器操作被调用时不会被填充。
如果您的控制器操作签名看起来与此类似:
public ActionResult PageASPX(string page, string pagetype)
{
...
}
即使您将它们作为查询变量而不是 URL 段提供,这两个参数仍可能会被填充。唯一的要求是路由不提供缺失段值的默认值(或者它们被设置为可选)。然后,默认 MVC 模型绑定器将page
使用实际查询变量值填充操作参数。
所以主要的是你应该改变你的路由定义(见我回答的最后一部分)。
应该工作的请求
为了让您的路由识别page
和pagetype
URL 段变量,您的请求应如下所示:
default.aspx/somepage
default.aspx/somepage/sometype
假设您的路由没有定义默认值page
,pagetype
那么当您的请求如下所示时,您的控制器操作将获取page
并pagetype
填充正确值的参数:
default.aspx/somepage
default.aspx/somepage/sometype
default.aspx?page=somepage
default.aspx?pagetype=sometype
default.aspx?page=somepage&pagetype=sometype
混合路由值和查询字符串变量
正如我的测试所示,Asp.net MVC 在具有值时不提供路由值覆盖(在 URL 本身中作为段或作为路由默认值提供)。在您的情况下,如果您请求此 URL:
default.aspx/routepage?page=querypage
您的操作方法会看到page
参数具有routepage的值。总是。
更重要的方面是,当您在路由定义本身中提供默认值时,即使您从 URL 中省略它,您也根本无法将其设置为查询字符串。为避免此问题,您有两种选择:
setpage
和pagetype
asUrlParameter.Optional
这将允许您在 URL 没有它们时用查询字符串变量覆盖它们的值 - 这意味着您始终可以只使用 URL 段或查询字符串,但不能同时使用两者,因为 URL 段占主导地位
URL 段变量和查询字符串变量具有不同的名称 - 缺点是您需要使用不希望的双参数进行操作:
public ActionResult PageASPX(string routePage, string routeType, string queryPage, string queryType)
{
string page = routePage ?? queryPage ?? string.Empty;
string type = routeType ?? queryType ?? string.Emtpy;
...
}
最佳解决方案
更改您的路由,以便为作为 URL 段提供的变量和作为查询字符串变量提供的变量分别定义路由定义。然后将这些路由连接到相同的控制器操作,只要所有变量(在段和查询字符串中)共享相同的名称:
route.MapRoute(
"InSegmentsBoth",
"default.aspx/{page}/{pagetype}",
new { controller = "Info", action = "PageASPX" }
);
route.MapRoute(
"InSegmentsPage",
"default.aspx/{page}",
new { controller = Info"", action = "PageASPX" }
);
route.MapRoute(
"InQueryString",
"default.aspx",
new { controller = "Info", action = "PageASPX" }
);
如果您的请求提供两个值(段和查询变量),如
default.aspx/segmentpage?page=querypage
然后段值优先,因此操作参数将page
具有此请求的段页值。