当我不想要它时,Url.Action重用路由数据

时间:2011-09-19 00:26:15

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

在我的布局页面中,构成我网站的主要部分的链接将通过以下调用进行呈现:

@SiteSectionLink("index", "blog", "blog")

SiteSectionLink是一个如下所示的助手:

@helper SiteSectionLink(string action, string controller, string display)
  {
  <li>
    <h1>
      <a class="site-section" href="@Url.Action(action, controller)">@display</a></h1>
  </li>
}

在实际的博客页面上,所有链接也引用“索引”操作,但也指定用于过滤帖子的日期参数(例如“blog / 4-2011”或“blog / 2010”)按日期。除此之外,还有一个可选的postID参数,用于引用特定的帖子。

为此,我有以下路线:

routes.MapRoute(
 "Blog", 
 "blog/{date}/{postID}", 
  new 
  { 
    controller = "blog", 
    action = "index", 
    date = UrlParameter.Optional, 
    postID = UrlParameter.Optional 
  } 
);

routes.MapRoute(
  "Default", // Route name
   "{controller}/{action}/{id}", // URL with parameters
    new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);

现在,问题是,当我点击了类似“blog / 11-2010”或“blog / 11-2010 / 253”的链接时,我的布局页面中的链接指向我的博客现在指的是当我希望它只链接到“blog /”而不是“blog / 11-2010”时的相同URL。

如果我更改SiteSectionLink助手以明确传递datepostID的null,如下所示:

<a class="site-section" href="@Url.Action(action, controller, 
  new { date = (string)null, postID = (int?)null})">@display</a></h1>

目前的路线值仍在使用,但现在看起来像“博客?日期= 11-2010”。

我看到this类似的问题,但接受的答案对我不起作用,我首先不使用ActionLink,我怀疑ActionLink会使用{ {1}}引擎盖下。

2 个答案:

答案 0 :(得分:3)

虽然您遇到的问题不是Phil Haack在this blog post中详细说明MVC3路由错误和带有两个可选参数的路由的行为,但我建议应用Phil帖子中描述的修复。

我还建议永远不要创建一个带有两个可选参数的路由,而是遵循将所需路由分成两个单独路由的模式。

答案 1 :(得分:1)

是Url.Action方法将参数放在查询字符串中。 您可以像这样更改助手:

@helper SiteSectionLink(string action, string controller, string display, string date = null, string id=null)
{ 
  <li> 
    @if (date == null)
    {
        <h1><a class="site-section" href="~/blog/@controller/@action">@display</a></h1> // simple workaround or better use P. Haack workaround
    }
    else 
    {
        <h1><a class="site-section" href="@Url.RouteUrl("blog", new { action = @action, controller = @controller, date = @date, id = @id })">@display</a></h1> 
    }
  </li> 
} 

所以你可以像这样使用SiteSelectionLink:

@SiteSectionLink("Index", "Blog", "test", "2011", "4")
@SiteSectionLink("Index", "Blog", "test2", "2011")
@SiteSectionLink("Index", "Blog", "test3")