切换到{controller} / {id} / {action}会中断RedirectToAction

时间:2011-07-06 13:14:42

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

我正在尝试使用REST正确的MVC网址。为此,我从以下位置切换了默认路由:

{controller}/{action}/{id}

{controller}/{id}/{action}

所以代替:

/Customer/Approve/23

现在有

/Customer/23/Approve

ActionLink似乎工作正常,但CustomerController中的以下代码:

[CustomAuthorize]
[HttpGet]
public ActionResult Approve(int id)
{
    _customerService.Approve(id);
    return RedirectToAction("Search");  //Goes to bad url
}

结束于网址/Customer/23/Search。虽然它应该转到/Customer/Search。它以某种方式记得23 (id)

这是我在global.cs中的路由代码

    routes.MapRoute(
        "AdminRoute", // Route name
        "{controller}/{id}/{action}", 
        new { controller = "Home", action = "Index", id = UrlParameter.Optional },
        new { id = new IsIntegerConstraint() }
        );

    routes.MapRoute(
        "Default", 
        "{controller}/{action}", 
        new { controller = "Home", action = "Index" });

如果我切换这两个功能,RedirectToAction开始工作,但使用:

Html.ActionLink("Approve", "Approve", new { Id = 23})

现在生成/Customer/Approve?id=23,而不是/Customer/23/Approve

我可以指定~/Customer/23/Approve之类的直接网址,而不是使用ActionLinkRedirectToAction,而是坚持使用MVC提供的功能。

6 个答案:

答案 0 :(得分:2)

当您在内部使用RedirectToAction()时,MVC将采用现有路由数据(包括Id值)来构建URL。即使传递null RouteValueDictionary,现有路径数据也将与新的空路径值数据合并。

我能看到的唯一方法是使用RedirectToRoute(),如下所示:

return RedirectToRoute("Default", new { controller = "Customer", action = "Search"});

counsellorben

答案 1 :(得分:1)

尝试在控制器中传入新的(空)RouteValueDictionary

return RedirectToAction("Search", new System.Web.Routing.RouteValueDictionary{});

在这里:

Html.ActionLink("Approve", "Approve", new { Id = 23})

我甚至不知道它如何接收客户控制器,因为您没有在任何地方指定它。尝试向ActionLink助手提供控制器和操作。

答案 2 :(得分:0)

尝试将当前路由数据传递给控制器​​操作中的方法:

return RedirectToAction("Search", this.RouteData.Values);

答案 3 :(得分:0)

删除此部分:

id = UrlParameter.Optional

可能会解决问题;当您将“id”定义为可选参数,并且您具有“默认”地图时,“默认”和“AdminRoute”是相同的! 问候。

答案 4 :(得分:0)

我遇到了类似的问题。当我尝试使用 RedirectToAction 重定向用户时,传递给我的控制器操作的路由值被重用,即使我没有在新的 RouteValueDictionary 中指定它们。我提出的解决方案(阅读后 advllorben的帖子)用于清除当前请求的 RouteData 。这样,我可以阻止MVC合并我没有指定的路由值。

所以,在你的情况下,也许你可以这样做:

[CustomAuthorize]
[HttpGet]
public ActionResult Approve(int id)
{
    _customerService.Approve(id);
    this.RouteData.Values.Clear();  //clear out current route values
    return RedirectToAction("Search");  //Goes to bad url
}

答案 5 :(得分:0)

我有类似的问题,并且能够通过将id添加到默认路由来解决它。

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

如果您的默认路线中确实没有ID,那么您也可以尝试:

routes.MapRoute(
    "Default", 
    "{controller}/{action}", 
    new { controller = "Home", action = "Index", id = string.Empty });