为什么这个路由参数被添加到查询字符串中?

时间:2011-08-16 22:19:11

标签: asp.net-mvc asp.net-routing

我有一个ASP.NET MVC 3应用程序,用于记录用户的计步器条目。用户可以访问/Pedometer查看所有最新的计步器条目,并可以通过访问/Pedometer/2011/Pedometer/2011/08和{{等网址来按年,年/月或年/月/日过滤1}},分别。

我在/Pedometer/2011/08/15创建了两个映射路径。第一条路由(如下所示)允许各种URL模式按日期过滤。第二个路由(未显示)是默认的ASP.NET MVC路由。

Global.asax

这是我的问题。我有一个视图,我想创建一个表单的链接:routes.MapRoute( "PedometerEntries", // Route name "Pedometer/{year}/{month}/{day}", // URL with parameters new { controller = "Pedometer", action = "Index", year = UrlParameter.Optional, month = UrlParameter.Optional, day = UrlParameter.Optional }, // Parameter defaults new { year = @"\d{4}", month = @"([012]?\d{1})?", day = @"(([1-9])|([12][0-9])|(3[0-1]))?" } // Parameter constraints ); ,它将允许用户以CSV格式下载所请求的URL的计步器条目。因此,如果用户正在访问currentUrl?format=csv,则下载链接将为/Pedometer。如果用户正在访问/Pedometer?format=csv,则下载链接将为/Pedometer/2011/08

要创建这样的链接,我添加了一个名为/Pedometer/2011/08?format=csv的自定义Html Helper,其代码如下:

DownloadToExcel

当我在我的视图中添加public static MvcHtmlString DownloadToExcel(this HtmlHelper helper, string linkText) { RouteValueDictionary routeValues = helper.ViewContext.RouteData.Values; // Add the format parameter to the route data collection, if needed if (!routeValues.ContainsKey("format")) routeValues.Add("format", "csv"); return helper.ActionLink(linkText, // Link text routeValues["action"].ToString(), // Action routeValues); // Route values } 标记时,它会生成一个链接,但这就是问题 - 当用户访问最近的条目或按年/月或年/月/日过滤的条目时,它按预期工作,但不是在用户访问年过滤网址时。

以下列表显示了用户访问的URL以及自定义Html Helper生成的相应URL:

  • 访问:@Html.DownloadToExcel() - 下载链接:/Pedometer
  • 访问:/Pedometer?format=csv - 下载链接:/Pedometer/2011
  • 访问:/Pedometer?year=2011&format=csv - 下载链接:/Pedometer/2011/08
  • 访问:/Pedometer/2011/08?format=csv - 下载链接:/Pedometer/2011/08/15

为什么访问/Pedometer/2011/08/15?format=csv时下载链接为/Pedometer/2011而非/Pedometer?year=2011&format=csv?为什么它不适用于那个案例,但按年/月和年/月/日的情况按预期工作?

由于

2 个答案:

答案 0 :(得分:6)

这个问题很可能是由Phil Haack在他博客上描述的this bug引起的。当你有两个连续的可选URL参数时,ASP.NET MVC 3中引入了一个回归错误。

答案 1 :(得分:4)

我使用您提供的代码创建了一个小型MVC 3应用程序,并获得与所描述的完全相同的行为。

如果我转到http://localhost:51181/pedometer/2011,生成的链接将为http://localhost:51181/Pedometer?year=2011&format=csv

但如果我明确输入了动作的名称(索引),它就会正确呈现。

访问http://localhost:51181/pedometer/index/2011会生成以下链接:

http://localhost:51181/pedometer/index/2011?format=csv

HtmlHelper扩展方法似乎并不总是使用正确的路由。

如果我在自定义路由下方添加以下路由,但在默认MVC路由之前,它可以正常工作。

routes.MapRoute(
    "PedometerDefault",
    "Pedometer/{year}",
    new { controller = "Pedometer", action = "Index", 
          year = UrlParameter.Optional }
);