MVC3区域和路由结构

时间:2012-07-07 07:08:03

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

我正在为用户,管理员,商店,论坛......制作区域

在每个区域中,它都有自己的Controllers,Models,Views文件夹。在根模型,根控制器和根视图中,我在其中共享了组件。

结构A:

Root/ -> Models/, Controllers/, Views/
Root/User/ -> Models/, Controllers/, Views/
Root/Admin/ -> Models/, Controllers/, Views/
Root/Shop/ -> Models/, Controllers/, Views/
Root/Forum/ -> Models/, Controllers/, Views/

我可能错了,但他们真的不觉得我在每个业务逻辑组中重复M V和C文件夹。我在想更好的结构是使用M V和C作为主文件夹并在其中布置我的业务逻辑组:

结构B:

Root/Views/ -> User/, Admin/, Shop/, Forum/ ...etc
Root/Models/ -> User/, Admin/, Shop/, Forum/ ...etc
Root/Controllers/ -> User/, Admin/, Shop/, Forum/ ...etc

但是如果我以这种方式构建文件夹,我丢失了区域(或从用户的角度来看,子文件夹路径)能够分割网站的逻辑功能。

e.g。

结构A,我可以这样做:

www.mywebsite.com/Users(area)/Account(controller)/LogOn(action)
www.mywebsite.com/Admin(area)/Account(controller)/LogOn(action) 

注意我可以使用不同区域的相同控制器和操作名称。

对于结构B,我能做的最好是:

www.mywebsite.com/AdminAccount(controller)/LogOn(action)
www.mywebsite.com/UserAccount(controller)/LogOn(action)

无区域无法实现单字子文件夹结果。如果不仅如此,这里的控制器名称可能会很快变得更加混乱。更不用说你有一大堆动作堆叠在同一个controller.cs文件中。

所以,无论如何,我的观点是,如果我发现结构B对我更有意义,我该如何配置路由来实现呢?

1 个答案:

答案 0 :(得分:1)

所以你想要结构B的url对应于A?

你将放弃对配置的约定。

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

        routes.MapRoute(
            "UserAccount", // Route name
            "users/account/{action}/{id}", // URL with parameters
            new { controller = "UserAccount", 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
        );
    }

另一种选择是编写自定义路由处理程序并引入您自己的约定。类似于以下内容(新的约定是连接用户和帐户以获取www.mywebsite.com/Users/Account/LogOn中的UsersAccountController)。我没有测试看看它是如何处理区域的,但是如果你有问题请告诉我,我可以看看。

public class CustomConventionRouteHandler : MvcRouteHandler
{
    protected override IHttpHandler GetHttpHandler(System.Web.Routing.RequestContext requestContext)
    {
        string controller = requestContext.RouteData.Values["controller"].ToString();

        object controllerModifier;
        if (requestContext.RouteData.Values.TryGetValue("controllerModifier", out controllerModifier))
        {
            requestContext.RouteData.Values["controller"] = string.Concat(controllerModifier, controller);
        }

        return base.GetHttpHandler(requestContext);
    }
}

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

    routes.Add(
        new Route(
            "{controllerModifier}/{controller}/{action}",
            new RouteValueDictionary(new { controllerModifier = UrlParameter.Optional, controller = "Home", action = "Index" }),  //defaults
            new CustomConventionRouteHandler()));
}