ASP.NET MVC - 嵌套路由/控制器

时间:2016-03-31 16:04:26

标签: c# asp.net-mvc

我有一个ASP.NET MVC应用程序。我见过类似的问题。但是,我还没有找到一个好的答案。基本上,我想使用以下路线:

/admin/users
/admin/users/create
/admin/users/[someId]
/admin/roles
/admin/roles/create
/admin/roles/[someId]

我有以下文件结构:

/Controllers
  AdminController.cs
  /Admin
    UsersController.cs
    RolesController.cs
/Views
  /Admin
    Index.cshtml
    /Users
      Index.cshtml
      Detail.cshtml
      Create.cshtml
    /Roles
      Index.cshtml
      Create.cshtml
      Detail.cshtml

当我运行我的应用时,我得到The resource cannot be found.

我做错了什么?我设置了断点,但没有一个被击中。这就像路线没有映射到控制器一样。我不知道我需要做什么。

3 个答案:

答案 0 :(得分:8)

您无需为此创建子文件夹。只需要2个控制器(UsersControllerRolesController),您就可以使用属性路由来定义所需的自定义路由模式。

假设您启用了属性路由

public class UsersController : Controller
{
  [Route("admin/users")]
  public ActionResult Index()  { // to do : Return something }

  [Route("admin/users/create")]
  public ActionResult Create()  { // to do : Return something }

  [Route("admin/users/{id}")]
  public ActionResult View(int id)  { // to do : Return something }    
}

或者您可以在控制器级别执行RoutePrefix

[RoutePrefix("admin/users")]
public class UsersController : Controller
{
  [Route("")]
  public ActionResult Index()  { // to do : Return something }

  [Route("create")]
  public ActionResult Create()  { // to do : Return something }

  [Route("{id}")]
  public ActionResult View(int id)  { // to do : Return something }    
}

你也可以为RolesControllers做同样的事情。

您可以在RegisterRoutes文件中的RouteConfig.cs方法中启用属性路由。

public static void RegisterRoutes(RouteCollection routes)
{            
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    routes.MapMvcAttributeRoutes(); //This line enables attribute routing 
   //Existing default Route definition goes here
}

您也可以考虑创建一个" Admin"区域并将您的控制器放在其中。如果您想对逻辑上的类似功能进行分组,Areas是正确的解决方案。

如果您不喜欢属性路由(为什么不呢?),您可以在RouteConfig中定义这些自定义路由模式。 您定义路线的顺序很重要。因此,请确保在默认通用路线之前定义您的特定路线

答案 1 :(得分:1)

您还可以通过使用RouteAttribute类修改操作方法来覆盖路线表。

例如:

class AdminController
{
    [Route("/admin/users/create")]
    public ViewResult CreateUser()
    {
        ...
    }
}

这样做的好处是可以将方法名称与url组件分开。

您还可以将多个网址路由到单个方法:

class AdminController
{
    [Route("/admin/users/{someId:guid}")]
    [Route("/admin/users/{someId:guid}/details")]
    public ViewResult UserDetails(Guid someID)
    {
        ...
    }
}

正如梅森所说,文件结构在MVC路由中并不重要。

答案 2 :(得分:0)

如果要使用基于约定(文件夹)的路由,可以使用MvcCodeRouting完全按照此处指定的方式执行操作。它默认使用命名空间,因此当您在层次结构中添加控制器时,它将自动生成同一层次结构中的路由。无需在任何地方应用MapChangeRemoveListener属性并手动设置路线。