【问题标题】:Why is this route parameter tacked onto the querystring?为什么将此路由参数附加到查询字符串上?
【发布时间】:2011-10-28 11:36:34
【问题描述】:

我有一个记录用户计步器条目的 ASP.NET MVC 3 应用程序。用户可以通过访问/Pedometer 来查看所有最近的计步器条目,并且可以通过分别访问/Pedometer/2011/Pedometer/2011/08/Pedometer/2011/08/15 等URL 按年、年/月或年/月/日进行过滤。

我在Global.asax 中创建了两条映射路线。下面显示的第一个路由是允许按日期过滤的各种 URL 模式。第二个路由(未显示)是默认的 ASP.NET MVC 路由。

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
);

这是我的问题。我有一个要在其中创建表单链接的视图:currentUrl?format=csv,这将允许用户以 CSV 格式下载所请求 URL 的计步器条目。因此,如果用户访问/Pedometer,下载链接将是/Pedometer?format=csv。如果用户访问/Pedometer/2011/08,下载链接将是/Pedometer/2011/08?format=csv

为了创建这样一个链接,我添加了一个名为 DownloadToExcel 的自定义 Html Helper,代码如下:

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
}

当我在我的视图中添加@Html.DownloadToExcel() 标记时,它会生成一个链接,但问题是——当用户访问最近的条目或按年/月或年/月/日期过滤的条目时,它的工作原理是预期的,但不是当用户访问年份过滤器 URL 时。

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

  • 访问:/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而不是/Pedometer/2011?format=csv?为什么它不适用于那个情况,但在年/月和年/月/日的情况下可以按预期工作?

谢谢

【问题讨论】:

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


    【解决方案1】:

    我使用您提供的代码创建了一个小型 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 }
    );
    

    【讨论】:

    • 这看起来与 Phil Haack 在@George Stocker 的回答中的博客文章中推荐的解决方法相同。
    • 是的,看起来是这样。在此之前不知道这个错误。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-07-20
      • 1970-01-01
      • 2015-05-20
      • 2011-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多