2008-09-04 135 views
3

我正在尋找一些示例或路由的示例,以用於以下類型的場景:MVC路由中控制器的類別? (在獨立命名空間中複製控制器名稱)

做事情的一般示例是:{controller}/{action}/{id }

所以在做一個商店產品搜索的情況下,你就必須:

public class ProductsController: Controller 
{ 
    public ActionResult Search(string id) // id being the search string 
    { ... } 
} 

假設您有幾家商店做到這一點,你想,始終是有什麼辦法可以再有:{category}/{controller}/{action}/{id}

因此,您可以針對特定商店進行特定搜索,但是針對不同的商店使用不同的搜索方法?

(如果需要的店名比函數本身的網址更高的優先級)

或將它歸結爲:

public class ProductsController: Controller 
{ 
    public ActionResult Search(int category, string id) // id being the search string 
    { 
     if(category == 1) return Category1Search(); 
     if(category == 2) return Category2Search(); 
     ... 
    } 
} 

它可能不是一個很好的例子,但基本上這個想法是使用相同的控制器名稱,因此在幾種不同的情況下都有一個簡單的URL,或者您是否需要唯一的控制器名稱,並且沒有辦法將它們放在稍微不同的名稱空間/目錄中?

編輯補充:

其他原因,我想這是因爲我可能要具有類別的URL,並且某些控制器將只在某些類別的工作。

IE:

/本/搜索/項目/搜索+長期< - 工程

/是/搜索/項目/搜索+長期< - 將無法正常工作 - 因爲搜索控制器是不允許的。

+0

1.0版本中的「區域」概念是否解決了這個問題? – hometoast 2009-06-01 01:10:30

回答

1

沒有任何妥協的最好方法就是通過繼承IControllerFactory來實現自己的ControllerFactory。您將實現的CreateController方法處理創建控制器實例以處理RouteHandler和ControllerActionInvoker的請求。約定是在創建控制器時使用控制器的名稱,因此您需要重寫此功能。這將是您放置自定義邏輯以基於路由創建控制器的位置,因爲您將擁有多個具有相同名稱但位於不同文件夾中的控制器。然後,您將需要在應用程序啓動時註冊您的自定義控制器工廠,就像您的路線一樣。

您需要考慮的另一個方面是在創建控制器時查找您的視圖。如果您打算爲所有人使用相同的視圖,那麼您不應該做與使用的約定不同的任何事情。如果您還計劃組織您的視圖,則還需要創建自己的ViewLocator,並在控制器工廠中創建它時將其分配給控制器。

爲了瞭解代碼,我已經回答了幾個與這個問題有關的問題,但是這個問題在某種程度上是不同的,因爲控制器名稱是相同的。我收錄了供參考的鏈接。

另一條路線,但可能需要一些妥協將使用新的AcceptVerbs屬性。查看question瞭解更多詳情。我還沒有玩過這個新功能,但它可能是另一條路線。

4

我甚至發現它甚至沒有通過搜索,而是通過掃描通過this question的ASP .NET論壇。

利用這一點,你可以有相同名稱的控制器下的命名空間的任何部分,只要您符合哪些路由屬於哪一個命名空間(你可以爲每個路由多個命名空間,如果你需要的!)

但是從這裏開始,你可以放在你的控制器下的一個目錄下,所以如果你的控制器是「MyWebShop.Controllers」,你可以放一個「Shop1」目錄,命名空間爲「MyWebShop.Controllers.Shop1」

Then this Works:

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

     var shop1namespace = new RouteValueDictionary(); 
     shop1namespace.Add("namespaces", new HashSet<string>(new string[] 
     { 
      "MyWebShop.Controllers.Shop1" 
     })); 

     routes.Add("Shop1", new Route("Shop1/{controller}/{action}/{id}", new MvcRouteHandler()) 
     { 
      Defaults = new RouteValueDictionary(new 
      { 
       action = "Index", 
       id = (string)null 
      }), 
      DataTokens = shop1namespace 
     }); 

     var shop2namespace = new RouteValueDictionary(); 
     shop2namespace.Add("namespaces", new HashSet<string>(new string[] 
     { 
      "MyWebShop.Controllers.Shop2" 
     })); 

     routes.Add("Shop2", new Route("Shop2/{controller}/{action}/{id}", new MvcRouteHandler()) 
     { 
      Defaults = new RouteValueDictionary(new 
      { 
       action = "Index", 
       id = (string)null 
      }), 
      DataTokens = shop2namespace 
     }); 

     var defaultnamespace = new RouteValueDictionary(); 
     defaultnamespace.Add("namespaces", new HashSet<string>(new string[] 
     { 
      "MyWebShop.Controllers" 
     })); 

     routes.Add("Default", new Route("{controller}/{action}/{id}", new MvcRouteHandler()) 
     { 
      Defaults = new RouteValueDictionary(new { controller = "Home", action = "Index", id = "" }), 
      DataTokens = defaultnamespace    
     }); 
    } 

唯一的另一件事是它將引用仍在基本目錄中的視圖,因此如果將視圖放入目錄以匹配,則必須在將視圖名稱返回到控制器內時將其放入視圖名稱中。

相關問題