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

7

我是一个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

当我运行我的应用程序时,我只得到了“找不到资源”的错误提示。
我做错了什么?我设置了断点,但是没有一个被命中。就好像路由没有映射到控制器一样。但是我不确定我需要做什么。

2
你的文件结构并不重要,路由才是关键,但你没有在问题中包含它们。 - mason
1
默认情况下,您可以在App_Start文件夹中找到RouteConfig.cs。也许可以将其添加到您的问题中。 - Mr.N0body
3个回答

14
不需要创建子文件夹即可实现此操作。只需拥有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执行相同的操作。

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

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" 区域,并将您的控制器放在其中。如果您想逻辑上分组相似功能,区域是正确的解决方案。

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


有没有办法让我使用子文件夹?我将在管理路由下拥有很多控制器。这就是我想使用子文件夹的原因之一。 - user70192
您可以使用子文件夹。只要您的类名以“Controller”结尾,它就会被识别。如果您想要逻辑上分组功能/控制器,请考虑创建一个管理区域。 - Shyju

1
您可以使用RouteAttribute类来装饰您的操作方法,从而覆盖路由表。
例如:
class AdminController
{
    [Route("/admin/users/create")]
    public ViewResult CreateUser()
    {
        ...
    }
}

这样做的好处是将方法名与URL组件分离开来。
您还可以将多个URL路由到单个方法:
class AdminController
{
    [Route("/admin/users/{someId:guid}")]
    [Route("/admin/users/{someId:guid}/details")]
    public ViewResult UserDetails(Guid someID)
    {
        ...
    }
}

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

0

如果您想使用约定(文件夹)路由,您可以使用MvcCodeRouting来完全按照您在此处指定的方式进行操作。它默认使用命名空间,因此当您在层次结构中添加控制器时,它将自动在相同的层次结构中生成路由。无需在各处应用[Route]属性并手动设置路由。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接