2012-07-07 70 views
0

我正在为区域用户,管理员,商店,论坛...等MVC3区和路由结构

在每一个领域,它有自己的控制器,模型,视图文件夹。在根模型,根控制器和根视图中,我共享了它们中的组件。

结构答:

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

我也许错了,但他们真的不看干了重复中号V和C文件夹中的每个业务逻辑组。我在想一个更好的结构将使用MV和C作为主要的文件夹和布局我的业务逻辑组在其中:

结构B:

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

但如果我构建的文件夹就这样,我失去了该区域(或从用户的角度来看,子文件夹路径)分割网站逻辑功能的能力。

例如

与结构的,我可以这样做:

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文件中的动作。

因此,无论如何,我的观点是,如果我发现Structure B对我更有意义,那么我该如何去配置路由来实现呢?

+0

对于结构B,您可以重复一次。想象区域在您的应用中与自己的“项目”相似;从而更好地分离关注独立功能块。在这个观点中,只有结构A是有意义的。 – Lucero 2012-07-07 07:18:52

+0

@Lucero,在现实中,我们不能把地区看作自己的“项目”吗?例如用户区域,用户登录后,他会去“商店”或“论坛”区域,他们都是相关的,并使用许多共享组件。所以,它回到我关心的重复M V和C在每个文件夹和根文件夹。它看起来不太干DRY – Tom 2012-07-07 07:40:24

+0

一家商店或一个论坛有着根本的不同,尽管它们可能共享一些代码,但它们当然可以被看作是他们自己的“项目”。如果您使用MvcContrib的Portable Area方法(允许将MVC区域外部化到他们自己的类库项目中,创建真正的分隔并启用跨不同MVC站点的重用和可插入性),甚至是真正的项目。 – Lucero 2012-07-07 08:44:27

回答

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())); 
} 
+0

不错。你的第一部分代码看起来像我想要的。因为有两个地图路线。所以我相信/ UserAccount /和/ User/Account /将在浏览器中工作。我正在尝试。 – Tom 2012-07-07 08:37:36

+0

我认为你说得对,他们都工作。如果存在问题,您可以将约束添加到禁用/ UserAccount /的默认路由。也可以通过停止路线禁用它。如果您不禁止路由,您应该确认对像@ Url.Action这样使用路由表创建链接的东西没有影响。 – 2012-07-07 08:45:36

+0

注意,必须在路径'DataTokens'(value key:'area')中设置区域,框架才能查看指定控制器的区域。 – Lucero 2012-07-07 08:48:33