3

给定下面的控制器

public class MyController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    public ActionResult Test()
    {
        return RedirectToRoute(new { action = "Index" });
    }

}

而这个路由

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        "Route1",
        "Route1",
        new {controller = "Account", action = "Index"});

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

}

当我浏览到 My/Test 时,MyController 的测试操作按预期命中。然后RedirectToRoute结果使用 Route1,因为我已将 Action 指定为“Index”。由于我没有指定控制器,它默认为“帐户”。这按预期命中了 AccountController 的索引操作

如果我将路由更改为下面的代码,那么它的工作方式会有所不同,而不是我所期望的。当我浏览到 My/Test 时,它会重定向到 MyController 的 Index Action 而不是 HomeController 的 Index Action。

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

我知道什么时候RedirectToAction使用,然后 MVC 将推断出当前的控制器,因此这将重定向到 MyController 的索引操作,但 MVC 源代码中的代码注释说RedirectToRoute不会推断出当前的控制器,我希望通过第一个示例证明了这一点。

有人知道为什么会这样吗?

4

1 回答 1

2

始终使用当前请求值。Url.ActionUrl.RouteUrl(由 使用RedirectToRoute)之间的区别在于,它用当前请求值(在 MVC 中从不为空)Url.Action覆盖空值,controller而不是(它使它们为空)。请注意,空值与不存在、省略或未定义的值不同。actionUrl.RouteUrl

看看我写的关于路由的这篇文章:

UrlHelper.Action 方法集采用 actionName 和 controllerName 字符串参数。调用这些方法可以转换为等价于Url.RouteUrl(new { action = actionName, controller = controllerName }). 正如我们之前在不能使用 null 或空字符串作为没有参数的默认值中所验证的那样,对 actionName 和/或 controllerName 使用 null 可能会导致无法匹配所需的路由。因此,只要将 null 用于 actionName 和/或 controllerName,Url.Action 就会使用当前请求控制器和操作值。


澄清一下,第一个示例匹配 Route1,因为:

  1. 该路由没有标记,这意味着它不需要匹配的值。
  2. action 的值与默认值匹配。
  3. 该代码没有为控制器提供值。如果提供了一个值,则它需要是“帐户”才能匹配。

在第二个示例中,My 用作控制器的值,取自当前请求值,因为路由包含控制器令牌并且未提供值。

于 2012-08-02T14:22:31.147 回答