2012-07-07 69 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