2009-07-10 118 views
13

我需要實現一個MVC網站搭配以下網址:ASP.net MVC自定義路由處理程序/約束

  • 組別/產品/ 1 /維基
  • 組別/產品/ 2 /維基
  • 類別1 /子類別2 /產品/ 3 /維基
  • 類別1 /子類別2 /子類別3 /產品/ 4 /維基
  • 等等,等等

其中匹配標準是url以「wiki」結尾。

不幸的是,下面包羅萬象的工作只在URL的最後一部分:

routes.MapRoute("page1", // Route name 
       "{*path}/wiki", // URL with parameters 
       new { controller = "Wiki", action = "page", version = "" } // Parameter defaults 

我還沒有時間去通過MVC可擴展性選項,所以我想知道什麼是可能的選擇實施這個?任何示例/例子都會太棒了!

回答

15

正如你所提到的,catch-all參數只能出現在路由的末尾 - 你發佈的代碼會拋出運行時錯誤,如果你甚至試圖運行,會給你黃色的死亡屏幕你的申請。

構建自定義路由場景有幾個可擴展點。這些是 - Route,RouteBase和IRouteHandler。

您可以通過擴展RouteBase來創建要處理的路由的生成列表。通常情況下,您可以遵循具有構造函數的模式,該構造函數接受資源(控制器名稱),然後爲其分配負責的路由列表,然後將其映射到global.asax中。下面是一些示例代碼,您可以從建:

public class MyRoute : RouteBase 
{ 
    private List<Route> _routes = new List<Route>(); 

    public MyRoute(string resource) 
    { 
     // make a Resource property, not shown in this example 
     this.Resource = resource; 

     // Generate all your routes here 
     _routes.Add(
      new Route("some/url/{param1}", 
      new McvRouteHandler { 
       Defaults = new RouteValueDictionary(new { 
        controller = resource, 
        action = actionName 
       }), 
      Constraints = new RouteValueDictionary() 
     ); 
     _routes.Add(...); // another new route 
    } 

    public override RouteData GetRouteData(HttpContextBase context) 
    { 
     foreach (var route in _routes) 
     { 
      var data = route.GetRouteData(context); 
      if (data != null) 
      { 
       return data; 
      } 
     } 
     return null; 
    } 

    public override VirtualPathData GetVirtualPath(RequestContext context, RouteValueDictionary rvd) 
    { 
     foreach (var route in _routes) 
     { 
      var path = route.GetVirtualPath(context, rvd); 
      if (path != null) 
      { 
       return path; 
      } 
     } 
     return null; 
    } 
} 

要使用你的路由類,在你的Global.asax做routes.Add(new MyRoute("page1"));

如果你需要更多的控制,你可以實現一個IRouteHandler,而不是如上例所示爲你的路由創建MvcRouteHandlers(),使用你自己的IRouteHandler。這將允許您覆蓋從請求數據中選擇控制器的邏輯。

整個框架是非常可擴展的,但你需要學習很多才能正確地做到這一點。如果可以的話,我建議只要重新排列URL就可以利用catch-all參數。

+1

Elastic.Routing(https://github.com/lokiworld/Elastic.Routing)擴展了內置的MVC路由,併爲您提供了在路由的任何部分使用catch all以及其他一些好東西東西像可選的部分。 – BrutalDev 2013-10-08 05:36:22