校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃

主頁 > 知識庫 > 淺析ASP.NET路由模型工作原理

淺析ASP.NET路由模型工作原理

熱門標簽:天心智能電銷機器人 400電話辦理哪家性價比高 塔城代理外呼系統 地圖標注的公司有哪些 地圖標注專業團隊 地圖定位圖標標注 代理接電話機器人如何取消 濮陽外呼電銷系統怎么樣 遂寧市地圖標注app

ps:這是針對ASP.NET4.5版本的,好像在最新的5.0版本中加入了OWIN,徹底解耦了和Web服務器的耦合,我還沒有研究過,不敢妄言4.5的模型適用5.0。

action*0x1:大話ASP.NET模型

首先我們先來了解下一個請求的悲歡離合的命運,看看它的一生中所走過的蜿蜒曲折的道路。如下圖所示:

在如上所示的風光旖旎的畫卷中,我們可以看到一個“請求”從客戶端瀏覽器出發,經歷千山萬水到達服務器,服務器的內核模塊的HTTP.SYS熱情款待了它,對它進行簡單的修飾之后,就和它依依惜別了,因為HTTP.SYS知道它是一個有夢想的“請求”,它應該去它該去的地方,于是就把它送到了IIS。

IIS是片神奇的土地,這里有一位偉大的神靈叫做inetinfo.exe,于是它便去神靈的居所W3SVC服務(windows服務)祈禱,希望能給他一些指示,神靈通過查閱天書(IIS的配置文件),知道了它不是一般的靜態文件,不能把它直接送回去,應該讓它去它的族人開辦的加工廠(即對應網站的工作進程中)好好修習一番。

現任加工廠老大叫w3wp.exe,在IIS6以前是aspnet_wp.exe,其因為沒有管理好各個加工廠之間的地盤問題被罷免了(asp.net_wp.exe用一個進程寄宿所有的網站,用應用程序域進行分割的,結果導致網站之間相互影響),現任老大w3wp.exe通過一個網站一個進程的方式把問題解決了,因此順利上位。

初入加工廠的“請求”拜訪了門衛asp.net_isapi.dll,門衛發現它是第一個過來的“請求”,于是為它打開了工廠的生產車間(即第一個請求到達時,啟動了asp.net運行的環境,后來的請求就可以直接進入這個環境里。),并請車間主任ISAPIRuntime來負責它,主任興高采烈的來歡迎它(即ISAPIRuntime調用ProcessRequest(簡稱PR)方法,訪問當前請求所在的ecb句柄),并讓土里土氣的它換上了統一服裝HttpWorkRequest(即把請求進行簡單的封裝),然后叫來班長HttpRuntime,讓班長安排它的工作。

班長說:”車間里面有危險,你先穿上安全制服HttpContext。”(即通過PR方法把HttpWorkRequest封裝成HttpContext),然后去組長宿舍(HttpApplicationFactory)準備叫一個組長(HttpApplication)來帶領它,結果發現還沒有組長,班長只好去招聘一個新組長。

每一個組長都是經過嚴格訓練才能上崗的,先要熟讀入廠準則Global.asax(即先編譯Global.asax文件),再通過準則中Application_Start方法考驗(即調用Application_Start方法),如此這般方成為一代組長。每位新任組長第一件事就是把所有的車間模塊裝配好,并創建好車間管道(通過讀取配置文件,加載所有的IHttpModule,并調用他們的Init方法,一般init方法都是注冊管道事件,之后通過BuidStepManager方法,根據經典模式或者集成模式生成對應的StepManager)。

新任組長見到“請求”,二話不說直接啟動車間管道,將其丟進去。穿著安全制服HttpContext的“請求”要依次通過管道中所有的關卡(asp.net管道模型),其中在第7個關卡之后,生成了IHttpHandler類型的對象,并在第11個關卡之后執行該對象的ProcessRequest方法處理請求,在這里“請求”得到完美的加工塑造,生成了HttpResponse,再通過剩下的管道,實現了夢想的請求就沿著原路返回了。上圖中第11、12個事件之間描述的是WebForm的Page對象處理請求的流程(即頁面生命周期)。

至此,一個請求的跌宕起伏的人生就說完了,各位觀眾欲知路由模塊具體怎么發揮作用的,還請先捧個人場,右下角點個贊。

action*0x2:路由模型解析

通過上文我們知道組長HttpApplication對象會負責組裝所有的IHttpModule,它是如何加載的呢?我們觀察反編譯的代碼:

private void InitModules()
{
HttpModuleCollection modules = RuntimeConfig.GetAppConfig().HttpModules.CreateModules();
HttpModuleCollection other = this.CreateDynamicModules();
modules.AppendCollection(other);
this._moduleCollection = modules;
this.InitModulesCommon();
}

RuntimeConfig.GetAppConfig().HttpModules.CreateModules();通過這行代碼,我們可以清楚的發現它讀取了運行時的配置文件,那么我們打開運行時的配置文件以觀究竟。


果然在這里add了一個System.WebRouting.UrlRoutingModule類型。接下來我們再用反編譯工具看這個類型的源碼:

如我們所料UrlRoutingModule實現了IHttpModule接口,我們看看它的Init方法干了些什么?

protected virtual void Init(HttpApplication application)
{
if (application.Context.Items[_contextKey] == null)
{
application.Context.Items[_contextKey] = _contextKey;
application.PostResolveRequestCache += new EventHandler(this.OnApplicationPostResolveRequestCache);
}
}

對第7個事件PostResolveRequestCache注冊方法OnApplicationPostResolveRequestCache,那么這個方法又是干啥的呢?

public virtual void PostResolveRequestCache(HttpContextBase context)
{
RouteData routeData = this.RouteCollection.GetRouteData(context);//匹配路由,得到匹配結果RouteData。
if (routeData != null)
{
IRouteHandler routeHandler = routeData.RouteHandler;
if (routeHandler == null)
{
throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, SR.GetString("UrlRoutingModule_NoRouteHandler"), new object[0]));
}
if (!(routeHandler is StopRoutingHandler))
{
RequestContext requestContext = new RequestContext(context, routeData);
context.Request.RequestContext = requestContext;
IHttpHandler httpHandler = routeHandler.GetHttpHandler(requestContext);//獲取處理當前請求的IHttpHandler對象。
if (httpHandler == null)
{
object[] args = new object[] { routeHandler.GetType() };
throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, SR.GetString("UrlRoutingModule_NoHttpHandler"), args));
}
if (httpHandler is UrlAuthFailureHandler)
{
if (!FormsAuthenticationModule.FormsAuthRequired)
{
throw new HttpException(0x191, SR.GetString("Assess_Denied_Description3"));
}
UrlAuthorizationModule.ReportUrlAuthorizationFailure(HttpContext.Current, this);
}
else
{
context.RemapHandler(httpHandler);//映射:用當前IHttpHandler對象處理請求。
}
}
}
}

代碼已經加了注釋,3步走:匹配路由→獲取處理當前請求的IHttpHandler對象→映射:用當前IHttpHandler對象處理請求。之后會在第11、12個事件之間調用IHttpHandler對象的PR方法處理當前請求。

我們再整理下思路:ASP.NET先注冊了UrlRoutingModule模塊,他就是一個實現了IHttpModule接口的類,其Init方法就是在第7個事件上注冊一個方法,該方法先匹配路由,如果匹配成功了,則用匹配結果RouteData中的IHttpHandler對象映射到當前上下文中,這樣在之后第11、12個事件之間就會調用這個IHttpHandler對象處理請求。

那么問題來了,Route對象是什么時候注入進去的,IHttpHandler對象又是誰?

還記得路由規則是怎么添加的嗎?如下面代碼所示:

public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
var defaults = new RouteValueDictionary();
defaults.Add("name", "*");
//方式一:
//通過RouteTable的靜態對象Routes新增一個Route類型的對象。
RouteTable.Routes.Add("app", new Route("app/{name}", defaults, new MyRouteHandler()));
//方式二:
//通過RouteTable的靜態對象Routes的擴展方法新增一個路由規則。
RouteTable.Routes.MapPageRoute("default", "app/{name}", "~/WebForm1.aspx", false, defaults);
}
} 

這是我們經常用的兩種方式添加路由規則,方式一中有我們自己編寫的MyRouteHandler類型的實例作為參數,其實就是通過IRouteHandler接口返回一個IHttpHandler對象。

/// summary>
/// 實現了IRouteHandler接口的類型
/// /summary>
internal class MyRouteHandler : IRouteHandler
{
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
//返回一個Page對象,用于處理請求。
return new WebForm1();
}
} 

其實這兩種方式沒有本質上的區別,因為方式二中路由規則參數都會實例化一個Route對象的。

我們分析方式二的源代碼:

public Route MapPageRoute(string routeName, string routeUrl, string physicalFile, bool checkPhysicalUrlAccess, RouteValueDictionary defaults, RouteValueDictionary constraints, RouteValueDictionary dataTokens)
{
if (routeUrl == null)
{
throw new ArgumentNullException("routeUrl");
}
Route item = new Route(routeUrl, defaults, constraints, dataTokens, new PageRouteHandler(physicalFile, checkPhysicalUrlAccess));
this.Add(routeName, item);
return item;
} 

發現所有的路由規則參數都用來實例化一個Route對象了,其中參數physicalFile和checkPhysicalUrlAccess用來實例化PageRouteHandler對象了,其源碼如下:

public class PageRouteHandler : IRouteHandler
{
} 

這是一個實現了IRouteHandler接口的類型,而這個接口只有一個作用就是返回IHttpHandler對象,源碼如下:

[TypeForwardedFrom("System.Web.Routing, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=31bf3856ad364e35")]
public interface IRouteHandler
{
// Methods
IHttpHandler GetHttpHandler(RequestContext requestContext);
}

到這里我們的疑問就解開了,原來我們注冊的路由規則都實例化成了Route對象,Route的GetRouteData方法用來匹配路由,路由規則中的physicalFile和checkPhysicalUrlAccess用來實例化一個IHttpHandler實例,用來處理請求。

總結:ASP.NET的路由模型如下圖所示

有關ASP.NET路由模型工作原理小編就給大家介紹到這里,希望對大家有所幫助!

您可能感興趣的文章:
  • 使用Nopcommerce為商城添加滿XX減XX優惠券功能
  • 為ASP.NET MVC及WebApi添加路由優先級
  • IIS6 MVC4 路由失效 無法訪問的解決方法
  • NopCommerce架構分析(一)Autofac依賴注入類生成容器
  • NopCommerce架構分析之(三)EntityFramework數據庫初試化及數據操作
  • NopCommerce架構分析之(四)基于路由實現靈活的插件機制

標簽:麗江 重慶 吉林 婁底 汕頭 河南 本溪 宜春

巨人網絡通訊聲明:本文標題《淺析ASP.NET路由模型工作原理》,本文關鍵詞  淺析,ASP.NET,路由,模型,工作,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《淺析ASP.NET路由模型工作原理》相關的同類信息!
  • 本頁收集關于淺析ASP.NET路由模型工作原理的相關信息資訊供網民參考!
  • 推薦文章
    校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃
    97aⅴ精品视频一二三区| 亚洲视频综合在线| 国产色产综合色产在线视频| 免费观看久久久4p| 精品日韩欧美在线| 国产在线精品国自产拍免费| 久久伊人中文字幕| eeuss鲁片一区二区三区在线观看| 国产精品久久久久久久岛一牛影视 | 国产黄色91视频| 国产欧美日韩卡一| 91亚洲国产成人精品一区二三| 亚洲自拍与偷拍| 日韩精品一区二区三区四区视频| 国产成人av电影在线观看| 亚洲免费视频中文字幕| 88在线观看91蜜桃国自产| 国内不卡的二区三区中文字幕 | 国产精品私人影院| 欧美日韩激情在线| 成人久久18免费网站麻豆 | 蜜臀久久99精品久久久久宅男 | 成人免费电影视频| 五月婷婷另类国产| 国产精品美女一区二区三区| 欧美精品一卡两卡| 99国产精品视频免费观看| 秋霞影院一区二区| 玉足女爽爽91| 国产欧美va欧美不卡在线| 欧美精品日韩精品| 91免费在线看| 国产91精品一区二区麻豆网站 | 国产成人午夜99999| 亚洲va欧美va人人爽| 中文字幕第一页久久| 日韩欧美久久久| 欧美在线高清视频| 91影视在线播放| 成人国产精品免费观看动漫| 青青草原综合久久大伊人精品优势| 亚洲精品一二三区| **网站欧美大片在线观看| 精品粉嫩aⅴ一区二区三区四区| 精品视频一区二区三区免费| 91亚洲精品久久久蜜桃| 99久久精品国产一区| 成人免费电影视频| 99国产精品国产精品久久| 国产精品18久久久久久久久久久久| 美女视频网站黄色亚洲| 日韩国产欧美在线观看| 午夜精品免费在线观看| 亚洲午夜精品久久久久久久久| 国产精品国产精品国产专区不蜜| 国产欧美一区二区精品仙草咪| 国产清纯美女被跳蛋高潮一区二区久久w| 日韩写真欧美这视频| 欧美成人一区二区| 久久伊人蜜桃av一区二区| 久久久久久一二三区| 欧美极品少妇xxxxⅹ高跟鞋| 国产精品欧美一区二区三区| 最新不卡av在线| 亚洲电影你懂得| 蜜臀久久久久久久| 国产精品资源网| av中文字幕一区| 日本乱人伦aⅴ精品| 欧美日韩激情一区二区| 欧美tickling挠脚心丨vk| 国产欧美日韩麻豆91| 亚洲一区在线观看免费观看电影高清| 91香蕉视频污在线| 制服丝袜亚洲色图| 337p亚洲精品色噜噜| 国产午夜亚洲精品午夜鲁丝片 | 亚洲大片在线观看| 久久99这里只有精品| 国产精选一区二区三区| 91小视频在线观看| 日韩网站在线看片你懂的| 欧美高清一级片在线观看| 亚洲激情综合网| 男男视频亚洲欧美| www.爱久久.com| 欧美一级欧美三级| 亚洲视频一区在线观看| 无码av中文一区二区三区桃花岛| 精品中文字幕一区二区小辣椒| 成人午夜免费av| 这里是久久伊人| 中文字幕在线一区免费| 免费看日韩精品| 色婷婷av久久久久久久| 精品欧美一区二区在线观看| 一区二区三区在线观看动漫| 裸体一区二区三区| 在线观看亚洲专区| 国产人成亚洲第一网站在线播放| 亚洲成人av中文| 成人aaaa免费全部观看| 日韩欧美成人一区| 同产精品九九九| 91麻豆蜜桃一区二区三区| 久久蜜桃香蕉精品一区二区三区| 天天色 色综合| 色婷婷精品大在线视频| 国产精品全国免费观看高清| 国内外成人在线| 欧美xxx久久| 日本不卡的三区四区五区| 色成年激情久久综合| 国产视频911| 国产综合一区二区| 日韩精品在线网站| 青青青爽久久午夜综合久久午夜| 在线观看91精品国产入口| 中文字幕一区二区三区色视频 | 在线免费av一区| 一区二区三区在线观看网站| 成人黄动漫网站免费app| 中文字幕国产一区| av网站一区二区三区| 国产精品三级av| 不卡大黄网站免费看| 国产视频一区在线播放| 国产a视频精品免费观看| 国产清纯白嫩初高生在线观看91 | 欧美性猛交xxxxxxxx| 亚洲女同一区二区| 91蝌蚪国产九色| 综合激情网...| 一本久道久久综合中文字幕| 亚洲毛片av在线| 91丝袜国产在线播放| 有码一区二区三区| 欧美喷潮久久久xxxxx| 丝袜亚洲精品中文字幕一区| 欧美日韩国产在线观看| 午夜久久电影网| 精品国产免费久久| 岛国一区二区三区| 一区二区三区国产精华| 欧美日韩精品一区二区| 欧美aaaaa成人免费观看视频| 日韩欧美一级二级三级| 粗大黑人巨茎大战欧美成人| 1000精品久久久久久久久| 欧美性猛交一区二区三区精品| 欧美aaa在线| 亚洲国产高清在线| 99久久久久久99| 午夜精品影院在线观看| 国产色一区二区| 欧美四级电影在线观看| 精品一区二区影视| 综合在线观看色| 日韩女优电影在线观看| 成人精品国产免费网站| 亚洲国产sm捆绑调教视频 | 日韩美一区二区三区| 丁香一区二区三区| 亚洲电影一区二区| 国产欧美日韩在线视频| 欧美日韩国产在线观看| 国产成人av自拍| 午夜av电影一区| 国产精品天天摸av网| 欧美精品aⅴ在线视频| www.性欧美| 国模少妇一区二区三区| 亚洲自拍偷拍图区| 国产日韩欧美综合一区| 欧美日韩国产首页| 99热精品一区二区| 紧缚奴在线一区二区三区| 亚洲一区二区三区视频在线播放| 久久亚洲综合av| 欧美喷潮久久久xxxxx| 91浏览器在线视频| 国产精品66部| 九色综合国产一区二区三区| 亚洲午夜免费电影| 亚洲日本护士毛茸茸| 久久久久久亚洲综合| 日韩免费成人网| 91精品国产一区二区三区蜜臀| 99久久国产综合精品麻豆| 国内精品视频666| 青青草国产精品97视觉盛宴| 亚洲国产美国国产综合一区二区| 亚洲人成电影网站色mp4| 欧美国产日韩亚洲一区| 久久久av毛片精品| 久久在线观看免费| 国产欧美综合在线| 欧美激情艳妇裸体舞| 久久综合成人精品亚洲另类欧美 | 欧美日韩亚洲综合在线 欧美亚洲特黄一级|