2009-06-20 75 views
4

我一直在玩ASP.Net MVC一段時間了。我發現最困難的事情是路由表。ASP.Net MVC路由策略

我發現大多數例子都保留了默認路由。我發現這導致了很多錯誤,其中默認路由重定向到HomeController並且不存在的操作。導致奇怪的錯誤信息,你會看到一個簡單的404。

我最終解決了路由設置,我明確定義了所有控制器/操作組合,我希望允許在最終重新定位到所有控制器/操作組合一個顯示明智的錯誤信息的404頁面。

我在這裏錯過了什麼嗎?或者這確實是一種做事的好方法?


看着我得到的答案我想我最好澄清一下這個問題。

我試圖欺騙我正在建設的網站的路由方案。我注意到,當我在默認的{controller}/{action}/{id}路由中,我想要顯示404錯誤的所有類型的URL實際上被路由到HomeController並導致一些不可靠的錯誤消息。

我有點困惑,因爲大多數代碼示例只是保留在默認路由中。是否有原因存在或可以將其刪除?

我用現在的方案看起來有點像這樣

 routes.MapRoute("About", "About", new {controller = "Page", action = "About"}); 
     routes.MapRoute("SignIn", "SignIn", new {controller = "Page", action = "SignIn"}); 
     routes.MapRoute("SignOut", "SignOut", new {controller = "Page", action = "SignOut"}); 
     routes.MapRoute("Authenticate", "Authenticate", new { controller = "Authentication", action = "Authenticate" }); 

     routes.MapRoute("CatchAll", "{*url}", new { controller = "Error", action = "Http404" }); 

我已經得到了系統中的每一個動作所指定的路線。最後還要顯示一個404。這是一個很好的方法來做到這一點,或者有一種更簡單的方法來使路由方案更加簡單嗎?

+0

我在同一條船上來的。我認爲如果默認路線無法找到控制器+操作,則所有捕獲都會起作用。相反,控制器工廠會拋出異常。你還在走的是明確的路線嗎? – dotjoe 2010-04-01 16:26:08

回答

7

如果這是您使用的是默認路由:

routes.MapRoute(
      "Default",            
      "{controller}/{action}/{id}",       
      new { controller = "Home", action = "Index", id = "" } 
     ); 

則「的HomeController」和「索引」的行動將被默認使用,除非您的網址另有規定。

例如:

http://www.something.com/」將使用主控制器的索引操作,因爲這些都是默認的控制器和行動。

http://www.something.com/foo」將使用Foo控制器的索引操作,因爲「索引」是默認操作。

http://www.something.com/foo/bar」將使用美孚控制器的「酒吧」行動

http://www.something.com/foo/bar/1」將使用美孚控制器的「酒吧」行動,通過「1」作爲「ID」參數

如果你不沒有「FooController」,任何以「http://www.something.com/foo」開頭的內容都將失敗。同樣,如果您的FooController沒有「Bar」動作,那麼「http://www.something.com/foo/bar」將會失敗。

您可能已經知道我上面發佈的所有內容。如果是這種情況,你會發布失敗的URL,所以我們可以提供更好的幫助嗎?

+0

你實際上沒有回答我的問題(我想這是我提出模糊問題的錯誤),但是你確實澄清了其他一些我不知道的事情,謝謝:-)我嘗試清除這個問題。 – Mendelt 2009-06-20 15:28:11

2

我更喜歡爲每個操作方法明確設置路徑。

結賬this

+0

感謝您的指針,將檢查了這一點! – Mendelt 2009-06-20 15:12:54

0

這個問題有點老,但我剛碰到它,有同樣的問題。

我並不太熱衷於手動定義大量路線,也不熱衷於添加一些屬性來爲我自動創建路線(Arnis的鏈接)。

經過一番考慮後,我決定使用我創建的簡單RouteConstraint。我修改了默認路由使用它,並添加默認下面我404包羅萬象的,就像這樣:

 
routes.MapRoute(
    "Default", 
    "{controller}/{action}/{id}", 
    new { controller = "Home", action = "Index", id = "" }, 
    new { controller = new ExistingControllerActionConstraint() } 
); 

routes.MapRoute(
    "CatchAll", 
    "{*catchall}", 
    new { controller = "Home", action = "NotFound" } 
); 

和約束類:

 
public class ExistingControllerActionConstraint : IRouteConstraint 
{ 
    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) 
    { 
     Type t = Type.GetType("MvcApplication_BareMinimum7.Controllers." + values["controller"] + "Controller"); 

     if (t == null) 
     { 
      return false; 
     } 

     MethodInfo mi = (from m in t.GetMethods() where m.Name == values["action"].ToString() select m).FirstOrDefault(); 

     return (mi != null); 
    } 
} 

反思的成本和LINQ使用可能超過註冊數百條路線的成本,但這對我來說似乎更清潔。