ASP.NET Core 2.1 : 十五.图解路由(2.1 or earler)(转)
ASP.NET Core 系列目錄
本文通過(guò)一張圖來(lái)看一下路由的配置以及請(qǐng)求處理的機(jī)制。
一、概述
路由主要有兩個(gè)主要功能:
這兩個(gè)功能看起來(lái)這兩個(gè)是相反的。
A.路由的配置
路由的兩個(gè)功能都離不開一個(gè)基本的操作:路由的基本配置。在Startup中默認(rèn)通過(guò)?routes.MapRoute(name: "default",template: "{controller=Home}/{action=Index}/{id?}")定義,
當(dāng)然我們還可以繼續(xù)?routes.MapRoute(。。。);? 這樣就定義了一系列的路由匹配方式組成一個(gè)路由表,例如這樣:
app.UseMvc(routes => {routes.MapRoute(name: "test", template: "Hello");routes.MapRoute("flylolo/{code}/{name}", MyRouteHandler.Handler);routes.MapRoute(name: "default", template: "{controller=Home}/{action=Index}/{id?}"); });每一個(gè)MapRoute會(huì)生成一個(gè)Route,第二個(gè)MapRoute看起來(lái)有些特殊,我們可以傳入一個(gè)自定義的RequestDelegate(本例為MyRouteHandler.Handler)來(lái)處理“flylolo/{code}/{name}”這樣的請(qǐng)求,
public static class MyRouteHandler{public static async Task Handler(HttpContext context){await context.Response.WriteAsync("MyRouteHandler");}}它會(huì)被封裝成一個(gè)RouteHandler(new RouteHandler(MyRouteHandler.Handler))賦值給Route的target屬性,而對(duì)于另外兩種沒(méi)有指定的,Route的target屬性默認(rèn)會(huì)被指定為MvcRouteHandler?,如下圖:
B.Handler的選擇
當(dāng)請(qǐng)求進(jìn)入之后,根據(jù)此路由表對(duì)該URL進(jìn)行逐一匹配,并將請(qǐng)求交給匹配到的路由的target(即MvcRouteHandler或RouteHandler),調(diào)用?_target.RouteAsync(context);?,在這個(gè)方法中,若是MvcRouteHandler會(huì)對(duì)請(qǐng)求的Controller和Action驗(yàn)證,若驗(yàn)證成功,則對(duì)context(是一個(gè)RouteContext)的Handler屬性賦值一個(gè)匿名方法;若是RouteHandler則會(huì)直接將其封裝的RequestDelegate(本例為MyRouteHandler.Handler)賦值給RouteContext.Handler.
C.請(qǐng)求處理
經(jīng)過(guò)Handler的選擇后,若RouteContext.Handler不為空,則調(diào)用RouteContext.Handler(HttpContext)對(duì)請(qǐng)求進(jìn)行處理。
D.其他
回想一下中間件,這個(gè)是不是和app.Map("/test", XXHandle)這樣配置中間件的方式有點(diǎn)像,當(dāng)請(qǐng)求路徑是/test的時(shí)候,請(qǐng)求交由XXHandle處理,同樣是Map,對(duì)比著更容易理解。
下面通過(guò)一張圖看一下路由配置和請(qǐng)求處理的流程。
二、流程及解析
?
? 為了方便查看,對(duì)幾個(gè)“重點(diǎn)對(duì)象”做了顏色標(biāo)識(shí)(點(diǎn)擊圖片可以看大圖):
?
RouteBuilder
?
? ? ? ? ? ①調(diào)用RouteBuilder的Build方法,生成一個(gè)RouteCollection。
public IRouter Build(){var routeCollection = new RouteCollection();foreach (var route in Routes){routeCollection.Add(route);}return routeCollection;}?
? ? ? ? ? ②RouteCollection實(shí)現(xiàn)IRouteCollection和IRouter接口,他是在Startup中的配置組成的集合。
? ? ? ? ? ③RouterMiddleWare就是專門用于進(jìn)行路由處理的中間件,在此將RouteCollection作為中間件RouterMiddleWare的參數(shù),并將這個(gè)中間件插入管道中。
public class RouterMiddleware{private readonly IRouter _router; //就是RouteCollectionpublic async Task Invoke(HttpContext httpContext);}?
2.?請(qǐng)求處理流程
? ? ? ④請(qǐng)求的處理流程在RouterMiddleWare的invoke()方法中。
? ?⑤請(qǐng)求首先會(huì)被封裝成一個(gè)RouteContext,本質(zhì)就是將httpContext、_router(也就是RouteCollection)包裝到一個(gè)對(duì)象里。
var context = new RouteContext(httpContext);context.RouteData.Routers.Add(_router); public class RouteContext {private RouteData _routeData;public RequestDelegate Handler ;public HttpContext HttpContext;//簡(jiǎn)單的賦值public RouteData RouteData; }? ? ? ? ? ⑥調(diào)用_router(也就是RouteCollection)的RouteAsync(context)方法,在其中遍歷每一個(gè)路由
? ? ? ? ? ⑦若與請(qǐng)求URL匹配,則將對(duì)應(yīng)的Handler賦值給context.Handler。
public async virtual Task RouteAsync(RouteContext context){// 快照備份var snapshot = context.RouteData.PushState(null, values: null, dataTokens: null);//遍歷for (var i = 0; i < Count; i++){var route = this[i];context.RouteData.Routers.Add(route);try{await route.RouteAsync(context);//若匹配,則給context.Handler賦值if (context.Handler != null){break;}}finally{if (context.Handler == null){snapshot.Restore();//通過(guò)快照還原}}}}? ? ? ? ? ? ? ⑧在RouterMiddleWare的invoke()方法中,調(diào)用新賦值的context.Handler處理HttpContext;
httpContext.Features[typeof(IRoutingFeature)] = new RoutingFeature() {RouteData = context.RouteData, };await context.Handler(context.HttpContext);?三、其他
? ? ? 由于文章寫的比較早各種原因一直沒(méi)有寫完,現(xiàn)在發(fā)現(xiàn)2.2版本之后,啟用了新的路由方案,還是把這章完成了發(fā)出來(lái),有愿意看的可以參考一下,下一篇文章介紹一下2.2版的新的路由方案,至于通過(guò)路由生成URL部分,就暫時(shí)不寫了。
?ASP.NET Core 系列目錄
原文地址:https://www.cnblogs.com/FlyLolo/p/ASPNETCore2_15.html
轉(zhuǎn)載于:https://www.cnblogs.com/NetPig/p/10671288.html
總結(jié)
以上是生活随笔為你收集整理的ASP.NET Core 2.1 : 十五.图解路由(2.1 or earler)(转)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 优化出现的小问题
- 下一篇: asp.net ajax控件工具集 Au