MVC路由和区域 - 如何构建匹配区域中默认控制器操作的路由?

时间:2012-09-26 23:09:37

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

我有一个简单的MVC4网站,其中包含一个名为“HomeController”的控制器区域(称为“User”)。

在此控制器上有两种操作方法:索引和详细信息:

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

    public ActionResult Details(int id)
    {
        return View();
    }
}

“UserAreaRegistration.cs”类如下:

public class UserAreaRegistration : AreaRegistration
{
    public override string AreaName
    {
        get
        {
            return "User";
        }
    }

    public override void RegisterArea(AreaRegistrationContext context)
    {
        context.MapRoute(
            "User_default",
            "User/{controller}/{action}/{id}",
            new { controller = "Home", action = "Index", id = UrlParameter.Optional },
            namespaces: new[] { "MvcApplication1.Areas.User.Controllers" }
        );

        context.MapRoute(
            "User_default_no_contoller",
            "User/{action}/{id}",
            new { controller = "Home", action = "Index", id = UrlParameter.Optional },
            namespaces: new[] { "MvcApplication1.Areas.User.Controllers" }
        );
    }
}

还有一个控制器不在名为“HomeController”的区域中:

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

RouteConfig.cs(非区域路由)如下:

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

        routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
            namespaces: new[] { "MvcApplication1.Controllers" }
        );
    }
}

我可以通过

访问“主页”
  • /
  • /主页
  • /主页/索引

我也可以在“用户”区域中进行“索引”操作

  • /用户

无法做的是找出如何在名为“详细信息”的区域中访问控制器上的其他方法:

  • / User / Details / 5不起作用,它返回404

我还注意到,尝试显式访问Index方法也没有正确路由:

  • /用户/索引不起作用,它返回404

我做错了什么?

是否可以在区域中“默认”控制器的控制器上使用“索引”以外的任何操作方法?

3 个答案:

答案 0 :(得分:4)

你的第一条路线上有太多违约,所以它吞没了一切。

  • URI /User/Details/5 User_default 路由匹配(Controller:“Details”和Action:“5”)。
  • URI /User/Index也匹配第一条路线(控制器:“索引”和默认操作:“索引”)

接近路线的方法是

  • 首先选择最具选择性的路线
  • 并仅设置必要的最小默认值
  • 使用route constraints确保MVC路由器不会尝试错误地匹配参数(即,为 int 参数提供一个数字约束的路由值)
  • 将最常用的路由(即 User_default )放在最后(作为不匹配任何更具体路由的URI的全能)

我会尝试设置这样的区域路线。

context.MapRoute(
        "User_default_no_contoller",
        "User/{action}/{id}",
        defaults: new { controller = "Home", id = UrlParameter.Optional },
        constraints: new { id = @"\d+" },
        namespaces: new[] { "MvcApplication1.Areas.User.Controllers" }
    );

context.MapRoute(
        "User_default",
        "User/{controller}/{action}/{id}",
        new { controller = "Home", action = "Index", id = UrlParameter.Optional },
        namespaces: new[] { "MvcApplication1.Areas.User.Controllers" }
    );

答案 1 :(得分:2)

克服这种“多默认值”问题的另一个建议是使用命名空间分开。

在您的示例中,我的建议是在名称空间“Areas.User”中使用Class UserAreaRegistration。随后您必须将HomeController放在命名空间“Areas.User.Controllers”的用户区中

它适用于我并保持代码清洁。

彼得

答案 2 :(得分:0)

感谢dbaseman的回答。它帮助我看看我自己的路由问题。我不确定我是否遇到了同样的问题,但这就是它的样子。

        routes.MapRoute("Tag", "Tag/{tag}", new { controller = "Blog", action = "Tag" });
        routes.MapRoute("Category", "Category/{category}", new { controller = "Blog", action = "Category" });
        routes.MapRoute("Post", "Archive/{year}/{month}/{day}/{title}", new {controller = "Blog", action = "Post"});
        routes.MapRoute("Action", "{action}", new { controller = "Blog", action = "Posts" });

当我的最后一条路线的“行动”参数高于任何其他路线时,“行动”下方的路线将不会被捕获。将它移到RouteConfig的底部允许它上面的所有部分现在成功命中。