【问题标题】:Url.Action reuses route data when I don't want it toUrl.Action 在我不希望时重用路由数据
【发布时间】:2011-11-19 21:24:21
【问题描述】:

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

@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>

当前路由值仍在使用,但现在看起来像“blog?date=11-2010”。

我看到this 类似的问题,但接受的答案对我不起作用,我一开始不使用ActionLink,我怀疑ActionLink 会在后台使用Url.Action

【问题讨论】:

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


    【解决方案1】:

    虽然您遇到的问题与 Phil Haack 在 this blog post 中详述的关于 MVC3 路由和具有两个可选参数的路由的错误的行为不太一样,但我建议应用 Phil 的帖子中描述的修复程序。

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

    【讨论】:

    • 感谢您在拆分路线方面的改进,您说得对,有两个可选项只会让人头疼。
    • 再想一想,我将其标记为答案,因为它是解决它的拆分,并结合向SiteSectionLink 添加重载。
    【解决方案2】:

    是的 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")
    

    【讨论】:

    • 谢谢,我向SiteSectionLink 添加了一个可选的routeValues 参数,将日期和postID 设置为空。我仍然很好奇它为什么会这样,什么时候想要这种行为?
    • Url.Action 方法在我们为与段变量不对应的属性提供值时使用查询字符串参数。在您的情况下,我认为这是由于 mvc 引擎将 url 解码为路由“blog”的方式,匹配未在匿名类型中传递的参数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-10
    • 2018-03-17
    • 1970-01-01
    • 1970-01-01
    • 2021-09-12
    • 1970-01-01
    • 2013-10-07
    相关资源
    最近更新 更多