【问题标题】:Route with optional parameter is not resolved correctly带有可选参数的路由未正确解析
【发布时间】:2011-08-20 03:56:36
【问题描述】:

这里是重现 ASP.NET MVC 3.0 路由的一个非常奇怪的问题的必要代码:

Global.asax.cs 中的路由注册:

routes.MapRoute("History", "Customer/History", new {controller = "User", action = "History", someParam = UrlParameter.Optional});
routes.MapRoute("Default", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional });

在这里,我们声明了一条通往用户历史记录的路线。但在 URL 中,我们想要“客户”而不是“用户”。另请注意参数someParam。控制器User 确实存在并且有动作History

现在使用情况:

<a href="<%= Url.Action("History", "User") %>">History</a>
<a href="<%= Url.Action("History", "User", new { someParam="qqq" }) %>">History with param</a>

我在这里使用Url.Action() 而不是Html.ActionLink() 只是为了清楚起见。

这是结果 - 这部分视图是如何呈现的:

<a href="/Customer/History">History</a>
<a href="/User/History?someParam=qqq">History with param</a>

现在问题很清楚了 - 不带参数的 URL 已正确解析,而带参数的 URL 以“/User”而不是“/Customer”开头。

问题:

  1. 这是正常行为吗?如果是,为什么路由会这样工作?
  2. 有什么解决方法吗?我的意思是有什么办法可以得到最终结果:

    <a href="/Customer/History">History</a>
    <a href="/Customer/History?someParam=qqq">History with param</a>
    

【问题讨论】:

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


    【解决方案1】:

    我怀疑它会让人感到困惑,因为您的客户路线没有列出额外的价值,但默认路线却列出了。试试这个:

    routes.MapRoute("History", "Customer/History/{someParam}", new {controller = "User", action = "History", someParam = UrlParameter.Optional});
    

    或保留查询字符串链接语法,这样:

    routes.MapRoute("History", "Customer/History/{id}", new {controller = "User", action = "History", id = UrlParameter.Optional});
    

    在第二种情况下,您在创建链接时不提供 id 值(您对 Url.Action 的调用不必更改)。

    【讨论】:

    • 感谢您的回复。根据您的建议,生成的 URL 将是 /Customer/History/qqq。但是我需要的是/Customer/History?someParam=qqq。有什么办法可以实现吗?
    • @Andrei - 好吧,你可以把 {id} 放在它上面而不是 {someParam},因为你没有给它一个 ID,它不会把 someParam 的值放在那里。您不必将 someParam 添加到路由设置中,只需在实际创建链接时将其添加为值(就像您已经在做的那样)。我已经用第二种形式更新了答案。
    • 非常感谢,现在它可以正常工作了。但是我仍然不确定添加默认参数如何解决问题。为什么原来的路线不适合?它具有与 Url.Action() 方法中给出的完全一样的控制器和动作, someParam 被声明为可选的 - 一切似乎都很好......你能告诉我我对这些可选参数有什么遗漏吗?
    • @Andrei - 老实说,我自己并不完全理解 为什么 它是这样工作的。我只知道确实如此。 :) 似乎是由于缺少第三个参数,路由在应该匹配时不匹配。在这种情况下,您并没有使用 {id},但是将它放在那里会让事情变得更快乐。如果我不得不猜测,我会认为它认为 someParam 适合它,即使它真的不适合。解决了这个问题,它可以按您的预期工作。
    • Tridus,实际上一切变得更加简单。 routes.MapRoute("History", "Customer/History", new {controller = "User", action = "History"}); 也能很好地完成这项工作 - Url.Action("History", "User", new { someParam="qqq" }) 给出了预期的 URL /Customer/History?someParam=qqq
    猜你喜欢
    • 1970-01-01
    • 2023-03-03
    • 2016-10-12
    • 2011-01-09
    • 2013-09-10
    • 1970-01-01
    • 2016-08-01
    • 2013-12-07
    相关资源
    最近更新 更多