• <fieldset id="8imwq"><menu id="8imwq"></menu></fieldset>
  • <bdo id="8imwq"><input id="8imwq"></input></bdo>
    最新文章專題視頻專題問(wèn)答1問(wèn)答10問(wèn)答100問(wèn)答1000問(wèn)答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
    問(wèn)答文章1 問(wèn)答文章501 問(wèn)答文章1001 問(wèn)答文章1501 問(wèn)答文章2001 問(wèn)答文章2501 問(wèn)答文章3001 問(wèn)答文章3501 問(wèn)答文章4001 問(wèn)答文章4501 問(wèn)答文章5001 問(wèn)答文章5501 問(wèn)答文章6001 問(wèn)答文章6501 問(wèn)答文章7001 問(wèn)答文章7501 問(wèn)答文章8001 問(wèn)答文章8501 問(wèn)答文章9001 問(wèn)答文章9501
    當(dāng)前位置: 首頁(yè) - 科技 - 知識(shí)百科 - 正文

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

    來(lái)源:懂視網(wǎng) 責(zé)編:小采 時(shí)間:2020-11-27 22:37:51
    文檔

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

    淺析ASP.NET路由模型工作原理:ps:這是針對(duì)ASP.NET4.5版本的,好像在最新的5.0版本中加入了OWIN,徹底解耦了和Web服務(wù)器的耦合,我還沒(méi)有研究過(guò),不敢妄言4.5的模型適用5.0。 action*0x1:大話ASP.NET模型 首先我們先來(lái)了解下一個(gè)請(qǐng)求的悲歡離合的命運(yùn),看看它的一生中所走過(guò)的蜿蜒曲折的
    推薦度:
    導(dǎo)讀淺析ASP.NET路由模型工作原理:ps:這是針對(duì)ASP.NET4.5版本的,好像在最新的5.0版本中加入了OWIN,徹底解耦了和Web服務(wù)器的耦合,我還沒(méi)有研究過(guò),不敢妄言4.5的模型適用5.0。 action*0x1:大話ASP.NET模型 首先我們先來(lái)了解下一個(gè)請(qǐng)求的悲歡離合的命運(yùn),看看它的一生中所走過(guò)的蜿蜒曲折的

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

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

    首先我們先來(lái)了解下一個(gè)請(qǐng)求的悲歡離合的命運(yùn),看看它的一生中所走過(guò)的蜿蜒曲折的道路。如下圖所示:

    在如上所示的風(fēng)光旖旎的畫(huà)卷中,我們可以看到一個(gè)“請(qǐng)求”從客戶端瀏覽器出發(fā),經(jīng)歷千山萬(wàn)水到達(dá)服務(wù)器,服務(wù)器的內(nèi)核模塊的HTTP.SYS熱情款待了它,對(duì)它進(jìn)行簡(jiǎn)單的修飾之后,就和它依依惜別了,因?yàn)镠TTP.SYS知道它是一個(gè)有夢(mèng)想的“請(qǐng)求”,它應(yīng)該去它該去的地方,于是就把它送到了IIS。

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

    現(xiàn)任加工廠老大叫w3wp.exe,在IIS6以前是aspnet_wp.exe,其因?yàn)闆](méi)有管理好各個(gè)加工廠之間的地盤問(wèn)題被罷免了(asp.net_wp.exe用一個(gè)進(jìn)程寄宿所有的網(wǎng)站,用應(yīng)用程序域進(jìn)行分割的,結(jié)果導(dǎo)致網(wǎng)站之間相互影響),現(xiàn)任老大w3wp.exe通過(guò)一個(gè)網(wǎng)站一個(gè)進(jìn)程的方式把問(wèn)題解決了,因此順利上位。

    初入加工廠的“請(qǐng)求”拜訪了門衛(wèi)asp.net_isapi.dll,門衛(wèi)發(fā)現(xiàn)它是第一個(gè)過(guò)來(lái)的“請(qǐng)求”,于是為它打開(kāi)了工廠的生產(chǎn)車間(即第一個(gè)請(qǐng)求到達(dá)時(shí),啟動(dòng)了asp.net運(yùn)行的環(huán)境,后來(lái)的請(qǐng)求就可以直接進(jìn)入這個(gè)環(huán)境里。),并請(qǐng)車間主任ISAPIRuntime來(lái)負(fù)責(zé)它,主任興高采烈的來(lái)歡迎它(即ISAPIRuntime調(diào)用ProcessRequest(簡(jiǎn)稱PR)方法,訪問(wèn)當(dāng)前請(qǐng)求所在的ecb句柄),并讓土里土氣的它換上了統(tǒng)一服裝HttpWorkRequest(即把請(qǐng)求進(jìn)行簡(jiǎn)單的封裝),然后叫來(lái)班長(zhǎng)HttpRuntime,讓班長(zhǎng)安排它的工作。

    班長(zhǎng)說(shuō):”車間里面有危險(xiǎn),你先穿上安全制服HttpContext。”(即通過(guò)PR方法把HttpWorkRequest封裝成HttpContext),然后去組長(zhǎng)宿舍(HttpApplicationFactory)準(zhǔn)備叫一個(gè)組長(zhǎng)(HttpApplication)來(lái)帶領(lǐng)它,結(jié)果發(fā)現(xiàn)還沒(méi)有組長(zhǎng),班長(zhǎng)只好去招聘一個(gè)新組長(zhǎng)。

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

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

    至此,一個(gè)請(qǐng)求的跌宕起伏的人生就說(shuō)完了,各位觀眾欲知路由模塊具體怎么發(fā)揮作用的,還請(qǐng)先捧個(gè)人場(chǎng),右下角點(diǎn)個(gè)贊。

    action*0x2:路由模型解析

    通過(guò)上文我們知道組長(zhǎng)HttpApplication對(duì)象會(huì)負(fù)責(zé)組裝所有的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();通過(guò)這行代碼,我們可以清楚的發(fā)現(xiàn)它讀取了運(yùn)行時(shí)的配置文件,那么我們打開(kāi)運(yùn)行時(shí)的配置文件以觀究竟。


    果然在這里add了一個(gè)System.WebRouting.UrlRoutingModule類型。接下來(lái)我們?cè)儆梅淳幾g工具看這個(gè)類型的源碼:

    如我們所料UrlRoutingModule實(shí)現(xiàn)了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);
    }
    }

    對(duì)第7個(gè)事件PostResolveRequestCache注冊(cè)方法OnApplicationPostResolveRequestCache,那么這個(gè)方法又是干啥的呢?

    public virtual void PostResolveRequestCache(HttpContextBase context)
    {
    RouteData routeData = this.RouteCollection.GetRouteData(context);//匹配路由,得到匹配結(jié)果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);//獲取處理當(dāng)前請(qǐng)求的IHttpHandler對(duì)象。
    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);//映射:用當(dāng)前IHttpHandler對(duì)象處理請(qǐng)求。
    }
    }
    }
    }

    代碼已經(jīng)加了注釋,3步走:匹配路由→獲取處理當(dāng)前請(qǐng)求的IHttpHandler對(duì)象→映射:用當(dāng)前IHttpHandler對(duì)象處理請(qǐng)求。之后會(huì)在第11、12個(gè)事件之間調(diào)用IHttpHandler對(duì)象的PR方法處理當(dāng)前請(qǐng)求。

    我們?cè)僬硐滤悸罚篈SP.NET先注冊(cè)了UrlRoutingModule模塊,他就是一個(gè)實(shí)現(xiàn)了IHttpModule接口的類,其Init方法就是在第7個(gè)事件上注冊(cè)一個(gè)方法,該方法先匹配路由,如果匹配成功了,則用匹配結(jié)果RouteData中的IHttpHandler對(duì)象映射到當(dāng)前上下文中,這樣在之后第11、12個(gè)事件之間就會(huì)調(diào)用這個(gè)IHttpHandler對(duì)象處理請(qǐng)求。

    那么問(wèn)題來(lái)了,Route對(duì)象是什么時(shí)候注入進(jìn)去的,IHttpHandler對(duì)象又是誰(shuí)?

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

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

    這是我們經(jīng)常用的兩種方式添加路由規(guī)則,方式一中有我們自己編寫(xiě)的MyRouteHandler類型的實(shí)例作為參數(shù),其實(shí)就是通過(guò)IRouteHandler接口返回一個(gè)IHttpHandler對(duì)象。

    /// <summary>
    /// 實(shí)現(xiàn)了IRouteHandler接口的類型
    /// </summary>
    internal class MyRouteHandler : IRouteHandler
    {
    public IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
    //返回一個(gè)Page對(duì)象,用于處理請(qǐng)求。
    return new WebForm1();
    }
    } 

    其實(shí)這兩種方式?jīng)]有本質(zhì)上的區(qū)別,因?yàn)榉绞蕉新酚梢?guī)則參數(shù)都會(huì)實(shí)例化一個(gè)Route對(duì)象的。

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

    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;
    } 

    發(fā)現(xiàn)所有的路由規(guī)則參數(shù)都用來(lái)實(shí)例化一個(gè)Route對(duì)象了,其中參數(shù)physicalFile和checkPhysicalUrlAccess用來(lái)實(shí)例化PageRouteHandler對(duì)象了,其源碼如下:

    public class PageRouteHandler : IRouteHandler
    {
    } 

    這是一個(gè)實(shí)現(xiàn)了IRouteHandler接口的類型,而這個(gè)接口只有一個(gè)作用就是返回IHttpHandler對(duì)象,源碼如下:

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

    到這里我們的疑問(wèn)就解開(kāi)了,原來(lái)我們注冊(cè)的路由規(guī)則都實(shí)例化成了Route對(duì)象,Route的GetRouteData方法用來(lái)匹配路由,路由規(guī)則中的physicalFile和checkPhysicalUrlAccess用來(lái)實(shí)例化一個(gè)IHttpHandler實(shí)例,用來(lái)處理請(qǐng)求。

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

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

    聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文檔

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

    淺析ASP.NET路由模型工作原理:ps:這是針對(duì)ASP.NET4.5版本的,好像在最新的5.0版本中加入了OWIN,徹底解耦了和Web服務(wù)器的耦合,我還沒(méi)有研究過(guò),不敢妄言4.5的模型適用5.0。 action*0x1:大話ASP.NET模型 首先我們先來(lái)了解下一個(gè)請(qǐng)求的悲歡離合的命運(yùn),看看它的一生中所走過(guò)的蜿蜒曲折的
    推薦度:
    標(biāo)簽: 原理 路由 模型
    • 熱門焦點(diǎn)

    最新推薦

    猜你喜歡

    熱門推薦

    專題
    Top
    主站蜘蛛池模板: 亚洲AV午夜福利精品一区二区| 国产午夜无码精品免费看| 一级做a爰黑人又硬又粗免费看51社区国产精品视 | 亚洲精品tv久久久久久久久 | 91精品国产综合久久婷婷| 久99久无码精品视频免费播放| 久久国产精品一区二区| 久久精品亚洲中文字幕无码麻豆| 久久精品国产一区二区| 欧美精品免费观看二区| 久久精品午夜一区二区福利| 免费精品久久久久久中文字幕 | 99精品国产一区二区三区2021| 亚洲欧美日韩精品久久亚洲区| 国产精品青青在线观看爽香蕉| 国产精品一在线观看| 久久99国产综合精品| 亚洲欧美日韩国产精品一区二区| 国产精品哟女在线观看| 久久99热国产这有精品| 国产精品久久波多野结衣| 国产欧美日韩精品丝袜高跟鞋| 亚洲国产精品VA在线看黑人| 无码精品第一页| 免费精品久久久久久中文字幕 | 国产欧美日韩综合精品二区| 亚洲国产精品lv| 久久久国产精品网站| 国产精品久久久久久久久鸭| 国产精品丝袜黑色高跟鞋| 国产午夜无码精品免费看动漫| 久久成人国产精品| 精品人无码一区二区三区| 久久国产精品无码HDAV| 久久免费的精品国产V∧| 亚洲精品字幕在线观看| 亚洲精品无码久久久| 午夜精品久久久内射近拍高清| 欧美日韩专区麻豆精品在线 | 国产精品特级毛片一区二区三区 | 国内精品久久久久久久97牛牛|