asp.net MVC 路由机制 Route
1:ASP.NET的路由機制主要有兩種用途:
??? -->1:匹配請求的Url,將這些請求映射到控制器
??? -->2:選擇一個匹配的路由,構造出一個Url
2:ASP.NET路由機制與URL重寫的區別
??? -->Url重寫關注的是將一個Url映射到另一個Url。
????? 路由機制關注的是將Url映射到資源上。資源不一定是一個物理頁面,可以是類中的方法。
??? -->Url重寫只能用于傳入的請求Url
????? 路由機制可以匹配傳入的Url,也能夠生成一個Url
??? -->Url重寫大多是IIS級別的,是IIS的一個組件
????? 路由機制是HttpModule級別,可以用代碼進行良好地控制
3:路由Url
???? RouteTable.Routes.MapRoute("simple","{first}/{second}/{third}');
???? 第一個參數是路由名稱,第二個參數是路由模式。
???? 路由系統會將客戶端請求的Url,依照路由模式進行解析,并將其解析到RouteValueDictionary實例的鍵/值中,存儲到RouteData中,可以通過RequestContext訪問RouteValueDictionary中的值。key就是路由模式中德參數名稱,值為請求url中的值。例如:
???? 請求的url為:/abc/display/123,那么解析到RouteData中的數據為:first="abc",second="display",third="123"
4:MVC中特殊的Url參數名稱-{controller}和{action}
???? 因為在MVC中,Url都會映射到控制器上的一個方法上,所以MVC框架需要使用一些特定的參數名稱{controller}{action}。{controller}參數用來實例化一個控制器類。按照約定優先的慣例,MVC將字符串Controller添加到{controller}參數值的后面,得到一個類名,然后根據這個類名查找實現了System.Web.Mvc.IController接口的類型,完成實例化。除了{controller}{action}之外,其他的參數當作控制器action方法的參數來處理。
???? RouteTable.Routes.MapRoute("simple","{controller}/{action}/{id}');
???? /abc/display/123請求會實例成abcController的控制器類,調用其中的display()方法,同時將123傳遞給display()方法的參數id
5:路由中的字面值
???? Url段中允許字面值和參數混合在一起。它僅有的限制就是不允許有兩個連續Url的參數
???? {language}-{country}/{controller}/{action}
???? {controller}.{action}.{id}
???? 這些都是合法的。
6:路由的默認值
???? 為Routes.MapRoute()方法傳遞一個默認值的字典。我們可以使用簡明的語法來定義字典,MapRoute()方法會在底層將簡明的語法new {controller="Home",action="Index",id=UrlparameterOptional}轉換成一個RouteValueDirectionary的一個實例。
???? -->1默認值對于Url參數位置十分重要,只有為當前參數后面的每一個參數都定義了默認值,路由才會采用當前參數的默認值,{controller}/{action}/{id},如果我們為{action}提供了默認值,沒有為{id}提供默認值,那么效果與不給{action}默認值是一樣的。下面例子:
???? RouteTable.Routes.MapRoute("simple1","{controller}/{action}/{id}",new {action="index"});
???? RouteTable.Routes.MapRoute("simple2","{controller}/{action}");
???? /abc/display這個Url只能匹配到simple2,因為只有為當前參數后面的每一個參數都定義了默認值,路由才會采用當前參數的默認值。
???? -->2任何帶有字面量的Url段在匹配請求的URL時,都禁止省略任何參數值。
???? RouteTable.Routes.MapRoute("simple","{controller}-{action}",new {action="Index"});
???? 它并不能匹配/abc-的請求,因為字面量-后面的參數{action}被省略了。
7:路由約束
??? 請求Url段的數量與路由模式中定義的參數個數能夠匹配上,那么路由就能匹配這個url,但是我們需要對Url有更多的控制,就需要使用路由約束。
??? 為Routes.MapRoute()方法傳遞一個正則表達式約束的字典。我們可以使用簡明的語法來定義字典,在方法的內部使用Regex類,將其轉換成RouteValueDirectionary類型的對象。
??? RouteTable.Routes.MapRoute("simple","{controller}/{action}/{id}",new {controller="Home",action="Index",Id=""},new {controller=@"\w+",action=@"\w+",id=@"\d+"});
??? -->自定義路由約束
?????? 除了正則表達式約束之外,我們可以實現IRouteConstraint接口,實現接口的Match()方法
?????? 系統已經為我們創建了一個實現IRouteConstraint接口的HttpMethodConstraint類,約束路由只能匹配指定的Http方法。
????? RouteTable.Routes.MapRoute("default","{controller}/{action}/{id}",null,new {httpMethod=HttpMethodConstraint("GET")});? 這個路由只能匹配Get請求。
?
8:路由名稱
??? -->1:在路由系統匹配請求的Url的時候,可以不需要用到路由名稱。但是在生成一個Url的時候,就需要一個已經定義的路由名稱,按照這個路由定義的規則,生成一個Url。在生成Url的時候,對路由選擇進行精確控制。
?
?
?????????? routes.MapRoute(
??????????????? name: "Default",
??????????????? url: "{controller}/{action}/{id}",
??????????????? defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
??????????? );
?
??????????? routes.MapRoute(
??????????????? name: "Test",
??????????????? url: "code/p/{action}/{id}",
??????????????? defaults: new {Controller="Home",action="index",id=UrlParameter.Optional }
??????????? );
??????? @Html.RouteLink("Test", "Test", new {? action = "indexTest",id=123 })
??????? ?選擇Test的路由,生成的Url是code/p/indexTest/123
?
??????? @Html.RouteLink("Default", "Default", new { controller = "homeTest", action = "indexTest",id=123 })
??????? 先擇Default路由,生成的Url是homeTest/indexTest/123
?????? -->2:在使用路由創建Url的時候,如果提供的路由有多余的,將被添加到url的后面,當作URL參數。
??? ????????@Html.RouteLink("Test", "Test", new {? action = "indexTest",id=123,para=456 })
??? ?????????選擇Test的路由,生成的Url是code/p/indexTest/123?para=456
??????????
9:MVC區域
??? 區域允許我們將模型,視圖和控制器分成單獨的功能節點。我們可以將大型復雜的網站分成若干個節點,方便管理。每一個區域都有單獨的路由系統。
??? 我們可以通過為每一個區域創建一個類,來配置區域路由。這個類要派生自AreaRegistration類,重寫其中的AreaName和RegisterArea成員。在Global.asax文件中,調用AreaRegistration.RegisterAllAreas()方法,就會調用每一個區域的RegisterArea()
?? -->區域路由的沖突。
????? 當在兩個區域中,當有兩個相同名稱的控制器,那么當前傳入的請求匹配沒有指定名稱空間的路由時,系統會拋出一個異常
?
9.1:名稱空間來區分控制器的優先順序
?? ?當輸入的一個Url請求與一條路由匹配時,如果有多個同一名稱的控制器,就會出現異常。我們可以在路由注冊的時候,對某些名稱空間制定優先級。
routes.MapRoute("myRoute","{controller}/{action}/{id}/{*catchall}",new{controller="Home",action="Index",id=UrlParameter.Optional},new[]{"MyNamespace"});
?
9.2:禁用后備的名稱空間
???? 可以告訴MVC路由系統,只查看指定的名稱空間。在這個指定的名稱空間下,如果找不到控制器,就停止搜素。
???? Route myRoute=routes.MapRoute("myRoute","{controller}/{action}/{id}/{*catchall}",new{controller="Home",action="Index",id=UrlParameter.Optional},new[]{"MyNamespace"});
???? myRoute.DataTokens["UserNamespaceFallback"]=fasle;
???? myRoute.DataTokens["UserNamespaceFallback"]=fasle此設置會傳遞到控制器工廠。
?
10:通量匹配catch-all
??? catch-all允許我們匹配任意數量的段的Url
??? RouteTable.Routes.MapRoute("default","{query/{query-name}}/{*extrastuff}")
??? /query/select/a/b/c? 參數{extrastuff}=a/b/c
??? /query/select/????? 路由仍能匹配{extrastuff}=""
??? 路由Url在與傳入的請求匹配時,它的字面量與請求精確匹配的,而參數是貪婪匹配的。每個Url參數都盡可能多地匹配文本。
??? RouteTable.Routes.MapRoute("defalut","{filename}.{ext}")
?
??? /asp.net.mvc.xml??????? {filename}=asp.net.mvc? {ext}=xml
??? 因為Url參數是貪婪匹配所以{filename}盡可能匹配多的文本,但需要給{ext}留下匹配的空間。
11:路由機制忽略請求的匹配
??? -->1:StopingRoutingHandler,在創建Route對象的時候,選擇處理程序
?????? 為RouteCollection添加路由Route,如果選擇StopingRoutingHandler來創建,那么就會忽略這個Route匹配的請求
?????? StopingRoutingHandler會忽略匹配請求的Url,將這個請求傳遞給標準的HTTP處理程序
?????? MvcRouteHandler會創建MVC路由對象,將這個請求傳遞給MvcRoute處理程序
??????? PageRouteHandler會創建ASP.NET路由對象,將這個請求傳遞給PageRoute處理程序
??????????? Route axdRoute = new Route("{resource}.axd/{*pathInfo}", new StopRoutingHandler());
??????????? routes.Add(axdRoute);
??????????? Route mvcRoutes = new Route("{resource}.axd/{*pathInfo}",new MvcRouteHandler());
??????????? Route pageRoutes = new Route("{resource}.axd/{*pathInfo}", new PageRouteHandler("~/Weather.aspx", true));
?
? ??????-->2:使用RouteCollection的擴展方法IgnoreRoute()忽略請求的Url
??????????????? RouteTable.Routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
12:路由的測試
?????? 我們可以使用RouteDebugger來測試路由
13:路由生成Url
????? 路由可以匹配請求的Url,那么也可以生成一個Url,這是一個完整的雙向系統。
????? -->1:調用RouteCollection.GetVirtualPath(),傳遞一個RequestContext對象,一個包含值得字典,一個Url路由名稱。
????? -->2:檢查路由的參數是否和字典提供的值相匹配,并檢查默認值,約束
????? -->3:依據字典提供的值,生成一個Url
????? -->4:溢出參數,如果字典中有多余的參數,那么這些參數會附加到Url,當作查詢字符串參數
???? ?@html和@url生成鏈接的方法,都是調用RouteCollection.GetVirtualPath()方法。
14:路由請求管道UrlRoutingModule
????? -->1:UrlRoutingModule使用在RouteTable中注冊的路由匹配當前請求。
????? -->2:匹配成功,路由模塊從匹配成功的路由對象Route中獲取IRouteHandler接口對象,一般MvcRouteHandler類就是這個實現。
????? -->3:路由模塊調用IRouteHandler接口的(就是MvcRouteHandler的實例)GetHandler()方法,返回用來處理請求的IHttpHandler對象,一般是MvcHandler。
????? -->4:調用實現IHttpHandler接口的HTTP處理程序對象的ProcessRequest()方法,將要處理的請求傳遞給她。
??? ??-->5:ASP.NETMVC中,MvcRouteHandler類就是IRouteHandler的實現,MvcRouteHandler返回一個實現了IHttpHandler接口的MvcHandler對象。MvcHandler對象用來實例化控制器類,調用控制器上面的方法。
?
15:路由數據RouteData
???? RouteCollection繼承自RouteBase,RouteBase定義了GetVirtualPath()方法和GetRouteData()方法,GetRouteData()方法,返回包含路由數據的字典對象RouteData
轉載于:https://www.cnblogs.com/guichi/p/4551665.html
總結
以上是生活随笔為你收集整理的asp.net MVC 路由机制 Route的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C#获取邮件客户端保存的邮箱密码
- 下一篇: .NET泛型解析(上)