【问题标题】:ASP.NET MVC3 Routing various subfolders to the same controllerASP.NET MVC3 将各种子文件夹路由到同一个控制器
【发布时间】:2011-11-13 09:07:30
【问题描述】:

我正在尝试将我的 MVC 项目设置为具有 URL,以便我可以转到:

/组/

/组/注册

/组/随便

但在我的控制器中,我也可以将某些操作标记为仅限管理员,以便在以下位置访问它们:

/管理员/组/删除/{id}

我想保留一个GroupController,并采取行动:

public class GroupController : Controller
{
    public ActionResult Index(){
        return View();
    }
    [AdminAction]
    public ActionResult Delete(int id){
        ...
        return View();
    }
}

允许:

/Groups 是一个有效的 URL。

/Admin/Groups 是一个有效的 URL(但会调用除索引之外的其他操作 - 也许)

/Admin/Groups/Delete/{id} 是一个有效的 URL(仅发布,随便)

/Groups/Delete 是一个无效的 url。

我意识到这可能是一个相当广泛的问题,但我是 MVC 的新手,我不确定从哪里开始寻找,所以如果你能指出我正确的方向,我将不胜感激。

【问题讨论】:

  • 为什么不直接设置一个管理控制器呢?如果我理解正确,您想要做的是拥有一些与公共组相关的功能,以及一些仅限管理员使用的功能。设置一个单独的管理控制器来关心管理,并在该控制器级别上设置授权。如果可能,不要混淆不相关的功能。分离关注点之类的东西,如果你想说流行语,但从长远来看真的更简单。
  • 对于较小的站点,我同意,但 Group 只是几个控制器之一,我不希望我的管理控制器增长为几十个操作。
  • @Valamas 现在还没有,但我对领域的了解还不够,不知道是否应该这样做。在 MVC3 方面,我是一个初学者。

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


【解决方案1】:

正如我们在下面的 cmets 中所讨论的,虽然可以使用我下面的原始答案来实现您要求的路由解决方案,但更好的解决方案是使用区域,建立一个 Admin 区域,并在您的 Admin 中创建控制器区域来处理不同对象的管理任务,如组、用户等。这使您可以更轻松地设置受限管理功能,既是一种更好的设计,也是一种更好的安全模型。

原始答案

你想要的可以通过以下路线来完成:

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

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

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

但是,正如 Akos 在 cmets 中所说,将管理功能分离到不同的控制器中是一种更好的设计。虽然这是可能的,但我建议不要使用这种设计。

更新

如果请求管理员操作,可以在默认路由上使用RouteConstraint 使其失败。默认路由如下所示:

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

RouteConstraint 看起来像这样:

public class IsNotAdminAction : IRouteConstraint 
{
    private string adminActions = "create~delete~edit";

    public IsNotAdminAction()
    { }

    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        // return false if there is a match
        return !adminActions.Contains(values[parameterName].ToString().ToLowerInvariant());
    }
}

【讨论】:

  • 这将如何防止 Groups/Delete/{id} 成为有效的 URL?我需要将一些操作隔离为仅限管理员。
  • 这将是一个很好的路线,但如果用户不是正确的角色,您的AdminAction 属性应该会抛出 403 错误。请注意,您可以添加RouteConstraint 以使默认路由在某些情况下失败,如上所示。但是,将管理操作分离到单独的控制器中仍然是一个更好的主意。
  • 我宁愿没有管理员控制器,因为会有很多“组”类型的控制器,我不想将每个管理员操作集中到一个庞大的控制器。我只是对区域进行了一些阅读,我想也许我想要一个“管理”区域,为每个需要管理功能的“普通”控制器和视图提供单独的控制器和视图。这看起来是一条合理的路线吗?
  • 我强烈建议您使用管理区域来执行不同的管理功能。这是一个比使用路由和 RouteConstraints 更好的解决方案。
  • 把它放在一个答案中,我会把它标记为正确的。非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-16
  • 2013-09-21
  • 2012-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多