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