2013-04-22 189 views
3

我試圖實現我自己的路由類,從默認路由繼承。ASP.NET MVC自定義路由類 - 無法獲取路由數據

這是我的自定義路由類的樣子:

public class FriendlyRoute : Route 
{ 
    public FriendlyRoute(string url, RouteValueDictionary defaults, IRouteHandler routeHandler) 
     : base(url, defaults, routeHandler) 
    { 

    } 

    public override RouteData GetRouteData(HttpContextBase httpContext) 
    { 
     var routeData = base.GetRouteData(httpContext); 

     var controllerName = routeData.Values["controller"].ToString(); 
     var actionName = routeData.Values["action"].ToString(); 

     routeData.Values["controller"] = fix(controllerName); 
     routeData.Values["action"] = fix(actionName); 

     return routeData; 
    } 

    private string fix(string name) 
    { 
     //Remove dashes: "my-controller" => "mycontroller" 
    } 
} 

我正在做的是接受與破折號URL和路由到正確的行動(「我的控制器/我的行動」,以「 MyController/MyAction「),但我有更多的計劃,這個自定義路由。

把我的自定義路由類的動作,我用下面的路線配置:

routes.Add("Default", 
      new FriendlyRoute("{controller}/{action}/{id}", 
          new RouteValueDictionary(new { controller = "Public", action = "Start", id = UrlParameter.Optional }), 
          new MvcRouteHandler())); 

這工作得很好!但是我對url結構並不滿意。我想擁有一些只有操作名稱(例如「/ about」,「/ contact」)和一些帶有控制器名稱(例如「/ mypage」,「/ mypage/invoices」)的URL。我使用默認路由類(不是我自己的自定義)開始,解決這個問題:

routes.Add("MyPages", 
      new Route("MyPage/{action}", 
        new RouteValueDictionary(new { controller = "MyPage", action = "Summary"}), 
        new MvcRouteHandler())); 

routes.Add("Public", 
      new Route("{action}/{id}", 
        new RouteValueDictionary(new { controller = "Public", action = "Start", id = UrlParameter.Optional }), 
        new MvcRouteHandler())); 

這也工作正常,但現在出現了與破折號的網址不支持。所以,我只是換在我的自定義路由類到路徑配置:

routes.Add("MyPages", 
      new FriendlyRoute("MyPage/{action}", 
          new RouteValueDictionary(new { controller = "MyPage", action = "Summary" }), 
          new MvcRouteHandler())); 

routes.Add("Public", 
      new FriendlyRoute("{action}/{id}", 
          new RouteValueDictionary(new { controller = "Public", action = "Start", id = UrlParameter.Optional }), 
          new MvcRouteHandler())); 

現在,當我跑我嘗試去到默認頁面(「/」)中的應用崩潰,因爲調用base.GetRouteData( httpContext)在我的FriendlyRoute.GetRouteData()返回null。

我都是新來創建一個自定義的路由類,所以任何暗示我做錯了將不勝感激。

回答

2

在添加額外的兩個路由之後,當根url被命中(「/」)時,將按照從上到下的順序處理路由定義來處理它,直到進行匹配。因此,現在對於第一條路線"MyPage/{action}",它將調用public abstract RouteData GetRouteData(HttpContextBase httpContext);方法,該方法將url與路徑定義進行匹配並檢查約束條件。如果匹配和約束檢查返回RouteValueDictionary對象,否則返回null。因此,對於第一個路由定義,它必然返回null,因爲url不匹配。您應該添加一個空檢查作爲foollowing

if (routeData != null) 
{ 
    var controllerName = routeData.Values["controller"].ToString(); 
    var actionName = routeData.Values["action"].ToString(); 

    routeData.Values["controller"] = Fix(controllerName); 
    routeData.Values["action"] = Fix(actionName); 
} 

相關的資源:Route.cs

希望這會有所幫助。

+0

好吧,我明白了。所有的路由定義都會被調用,直到找到一個匹配的路由,並且當url不匹配時它應該返回null。你讓我走向正確的方向。謝謝! :) – haagel 2013-04-23 08:07:47

+0

歡迎:) – shakib 2013-04-23 08:15:17