原文http://m.survivalescaperooms.com/zeusro/p/RouteConfig.html裝載注明出處,爬蟲請自重。
繼續延續坑爹標題系列。其實只是把aPRess.pro.asp.net.mvc.4.framework里的CHAPTER 13翻譯過來罷了,當做自己總結吧。內容看看就好,排版就不要吐槽了,反正我知道你也不會反對的。
先說一下基本的路由規則原則。基本的路由規則是從特殊到一般排列,也就是最特殊(非主流)的規則在最前面,最一般(萬金油)的規則排在最后。這是因為匹配路由規則也是照著這個順序的。如果寫反了,那么即便你路由規則寫對了那照樣坐等404.
XD 首先說URL的構造。 其實這個也談不上構造,只是語法特性吧。
routes.MapRoute(name: "Default",url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); Route myRoute = new Route("{controller}/{action}", new MvcRouteHandler());routes.Add("MyRoute", myRoute); routes.MapRoute("ShopSchema", "Shop/{action}", new { controller = "Home" }); 個人覺得第一種比較易懂,第二種方便調試,第三種寫起來比較效率吧。各取所需吧。本文行文偏向于第三種。
routes.MapRoute( "Default", // 路由名稱"{controller}/{action}/{id}", // 帶有參數的 URL new { controller = "Home", action = "Index", id = UrlParameter.Optional } // 參數默認值 (UrlParameter.Optional-可選的意思) );routes.MapRoute("ShopSchema2", "Shop/OldAction", new { controller = "Home", action = "Index" }); routes.MapRoute("ShopSchema", "Shop/{action}", new { controller = "Home" }); routes.MapRoute("ShopSchema2", "Shop/OldAction.js", new { controller = "Home", action = "Index" });沒有占位符路由就是現成的寫死的。
比如這樣寫然后去訪問http://localhost:XXX/Shop/OldAction.js,response也是完全沒問題的。 controller , action , area這三個保留字就別設靜態變量里面了。
routes.MapRoute("MyRoute2", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = "DefaultId" }); 這種情況如果訪問 /Home/Index 的話,因為第三段(id)沒有值,根據路由規則這個參數會被設為DefaultId
這個用viewbag給title賦值就能很明顯看出
ViewBag.Title = RouteData.Values["id"];
圖不貼了,結果是標題顯示為DefaultId。 注意要在控制器里面賦值,在視圖賦值沒法編譯的。
然后再回到默認路由。 UrlParameter.Optional這個叫可選URL段.路由里沒有這個參數的話id為null。 照原文大致說法,這個可選URL段能用來實現一個關注點的分離。剛才在路由里直接設定參數默認值其實不是很好。照我的理解,實際參數是用戶發來的,我們做的只是定義形式參數名。但是,如果硬要給參數賦默認值的話,建議用語法糖寫到action參數里面。比如:
public ActionResult Index(string id = "abcd"){ViewBag.Title = RouteData.Values["id"];return View();} routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}", new { controller = "Home", action = "Index", id = UrlParameter.Optional }); 在這里id和最后一段都是可變的,所以 /Home/Index/dabdafdaf 等效于 /Home/Index//abcdefdjldfiaeahfoeiho 等效于 /Home/Index/All/Delete/Perm/.....
這個提醒一下記得引用命名空間,開啟IIS網站不然就是404。這個非常非主流,不建議瞎搞。
routes.MapRoute("MyRoute","{controller}/{action}/{id}/{*catchall}", new { controller = "Home", action = "Index", id = UrlParameter.Optional },new[] { "URLsAndRoutes.AdditionalControllers", "UrlsAndRoutes.Controllers" }); 但是這樣寫的話數組排名不分先后的,如果有多個匹配的路由會報錯。 然后作者提出了一種改進寫法。
routes.MapRoute("AddContollerRoute","Home/{action}/{id}/{*catchall}",new { controller = "Home", action = "Index", id = UrlParameter.Optional },new[] { "URLsAndRoutes.AdditionalControllers" }); routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}", new { controller = "Home", action = "Index", id = UrlParameter.Optional },new[] { "URLsAndRoutes.Controllers" });這樣第一個URL段不是Home的都交給第二個處理 最后還可以設定這個路由找不到的話就不給后面的路由留后路啦,也就不再往下找啦。
Route myRoute = routes.MapRoute("AddContollerRoute", "Home/{action}/{id}/{*catchall}", new { controller = "Home", action = "Index", id = UrlParameter.Optional }, new[] { "URLsAndRoutes.AdditionalControllers" }); myRoute.DataTokens["UseNamespaceFallback"] = false; routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}", new { controller = "Home", action = "Index", id = UrlParameter.Optional }, new { controller = "^H.*"}, new[] { "URLsAndRoutes.Controllers"});routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}",new { controller = "Home", action = "Index", id = UrlParameter.Optional }, new { controller = "^H.*", action = "^Index$|^About$"}, new[] { "URLsAndRoutes.Controllers"}); routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}",new { controller = "Home", action = "Index", id = UrlParameter.Optional }, new { controller = "^H.*", action = "Index|About", httpMethod = new HttpMethodConstraint("GET") }, new[] { "URLsAndRoutes.Controllers" }); routes.MapPageRoute("", "", "~/Default.aspx"); routes.MapPageRoute("list", "Items/{action}", "~/Items/list.aspx", false, new RouteValueDictionary { { "action", "all" } }); routes.MapPageRoute("show", "Show/{action}", "~/show.aspx", false, new RouteValueDictionary { { "action", "all" } }); routes.MapPageRoute("edit", "Edit/{id}", "~/edit.aspx", false, new RouteValueDictionary { { "id", "1" } }, new RouteValueDictionary { { "id", @"/d+" } });具體的可以看
或者官方msdn
首先要在路由注冊方法那里
//啟用路由特性映射 routes.MapMvcAttributeRoutes();
這樣
[Route("Login")]route特性才有效.該特性有好幾個重載.還有路由約束啊,順序啊,路由名之類的.
[RoutePrefix("reviews")][Route("{action=index}")]public class ReviewsController : Controller{}// eg: /users/5[Route("users/{id:int}"]public ActionResult GetUserById(int id) { ... } // eg: users/ken[Route("users/{name}"]public ActionResult GetUserByName(string name) { ... }// eg: /users/5// but not /users/10000000000 because it is larger than int.MaxValue,// and not /users/0 because of the min(1) constraint.[Route("users/{id:int:min(1)}")]public ActionResult GetUserById(int id) { ... }| Constraint | Description | Example |
|---|---|---|
| alpha | Matches uppercase or lowercase Latin alphabet characters (a-z, A-Z) | {x:alpha} |
| bool | Matches a Boolean value. | {x:bool} |
| datetime | Matches aDateTimevalue. | {x:datetime} |
| decimal | Matches a decimal value. | {x:decimal} |
| double | Matches a 64-bit floating-point value. | {x:double} |
| float | Matches a 32-bit floating-point value. | {x:float} |
| guid | Matches a GUID value. | {x:guid} |