ASP.NET-MVC整體運(yùn)行原理走源碼_第1頁
ASP.NET-MVC整體運(yùn)行原理走源碼_第2頁
ASP.NET-MVC整體運(yùn)行原理走源碼_第3頁
ASP.NET-MVC整體運(yùn)行原理走源碼_第4頁
ASP.NET-MVC整體運(yùn)行原理走源碼_第5頁
已閱讀5頁,還剩12頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、MVC那些不為人知的一些事情有好些理解是直接寫在源碼里的,然后通過截圖,放到這個(gè)Word里面,所以圖很重要,有圖有證據(jù)嘛。有些不清晰的,就放大來看啦(Ctrl+滾輪上)哈哈MVC運(yùn)行的整體機(jī)制整體路線:瀏覽器發(fā)送請(qǐng)求IIS捕獲到請(qǐng)求,根據(jù)請(qǐng)求里面的信息找到對(duì)應(yīng)的程序集加載程序集,創(chuàng)建運(yùn)行環(huán)境包裝請(qǐng)求信息(wr) 調(diào)用HttpRuntime的PR方法創(chuàng)建application(讀取global文件,調(diào)用Application_Start方法)初始化(讀取配置文件(用戶+系統(tǒng)的),調(diào)用InitModlues()方法),第七個(gè)事件里注冊(cè)了UrlRoutingModules方法創(chuàng)建MvcHandler

2、,它包含了請(qǐng)求上下文信息,路由信息,并將其添加到上下文HttpContext調(diào)用MvcHandler的PR方法,創(chuàng)建控制器,調(diào)用action(用戶在Controller下面寫的方法),將用戶數(shù)據(jù)保存到父類里面。執(zhí)行action返回ViewResult(包含了用戶執(zhí)行后的數(shù)據(jù))拿取視圖引擎,調(diào)用Render()方法,生成Html代碼,創(chuàng)建視圖。能力有限,沒求甚解。愿互相學(xué)習(xí),互相指正,共同進(jìn)步。【你必須非常努力,才能看起來毫不費(fèi)力!】ASP.NET和MVC.NET的區(qū)別從UrlRoutingModules這個(gè)方法說起。.NET 程序運(yùn)行的時(shí)候,會(huì)先執(zhí)行初始化,也就是調(diào)用Global文件里的App

3、lication_Start方法。通過反射創(chuàng)建這個(gè)文件里的類(在ASP.NET里面就是Global類,在MVC下是MVCApplication類,它們繼承自HttpApplication類。) 如果Global文件不存在,就直接創(chuàng)建他們的父類:HttpApplication。接著在確保調(diào)用了Application_Start方法后,創(chuàng)建ApplicationInstance實(shí)例(對(duì)象池),然后進(jìn)行初始化。在.NETFrameWork 4.0,初始化時(shí)讀取配置文件web.config(包括系統(tǒng)配置文件和用戶自定義的配置文件)。在系統(tǒng)配置文件下有一個(gè)HttpModules。內(nèi)容如下:讀取HttpM

4、odules節(jié)點(diǎn),為其創(chuàng)建對(duì)應(yīng)的對(duì)象,循環(huán)調(diào)用里面的Init方法,在這個(gè)方法里,向application里面的事件注冊(cè)方法(用戶的代碼)。完成AOP編程。MVC 在配置文件里,寫了一個(gè)UrlRoutingModule,創(chuàng)建這個(gè)方法,在這個(gè)方法里的Init方法里,向管道事件的第七個(gè)事件注冊(cè)了一個(gè)方法。這個(gè)方法主要做的是將MVCHandler添加到上下文中(HttpContext).【下面這個(gè)圖是從瀏覽器請(qǐng)求開始的】那么要研究MVC就從這個(gè)UrlRoutingModule(繼承IHttpModule接口)方法開始研究。UrlRoutingModule類下的Init()方法在第七個(gè)事件下注冊(cè)了一個(gè)方

5、法:這個(gè)方法里:1、 拿到HttpApplication對(duì)象,2、 將上下文對(duì)象HttpContext封裝到HttpContextBase里面。3、 傳入上下文對(duì)象,執(zhí)行事件。-分割線- 1、 拿取路由數(shù)據(jù)。1.1根據(jù)上下文,進(jìn)行過濾,判斷請(qǐng)求的是不是一個(gè)已經(jīng)存在的文件,如果是,則直接返回這個(gè)文件。1.2如果請(qǐng)求的不是存在的文件,那么獲取路由數(shù)據(jù)。獲取路由數(shù)據(jù)的時(shí)候,調(diào)用的是RouteBase類下面的GetRouteData(httpContext)方法。 1.2.1RouteBase下的GetRouteData方法,但是,實(shí)現(xiàn)這個(gè)方法的類是Route。繼續(xù)看GetRouteData()方法:

6、因?yàn)樵赗eflector下不能寫注釋,我轉(zhuǎn)到了MVC源碼下面。到這里,是時(shí)候說明一下那個(gè)RouteHandler是哪里來的了。其實(shí)它就是MVCRouteHandler。我們到Global文件下去看。A:這里注冊(cè)路由,調(diào)用MvcApplication下的RegisterRoutes方法。即BB:將路由信息傳入到MapRoute下面,它其實(shí)就是返回一個(gè)Route對(duì)象回來。具體做了什么呢?上面我在1.2.2那里標(biāo)記了一下,那個(gè)就是Route類的一個(gè)構(gòu)造函數(shù)Route(string url,IRouteHandler routeHandler),然后在這里new了一個(gè)Route對(duì)象,并傳入了一個(gè)url

7、和一個(gè)MvcRouteHandler對(duì)象,因此,到這里,可以知道routeHandler 就是MvcRouteHandler。而上面已經(jīng)確定了,this就是Route,那么Route下的RouteHandler也就是MvcRouteHandler。參看1.2.3!在1.2.2里將routeHandler傳給1.2.3的RouteHandler。我們接著說GetRouteData()方法。簡單地說,GetRouteData就是拿取路由數(shù)據(jù),將MvcRouteHandler添加到RouteData對(duì)象里RouteData data=new RouteData(this,this.RouteHand

8、ler).但是在里面做了一些檢查,檢查路徑,檢查約束。最后返回這個(gè)data。還是看一下RouteData里面的內(nèi)容吧:這里面包含了MvcRouteHandler(RouteHandler),命名空間(dataTokens),路由數(shù)據(jù)?沒去研究RouteValueDictionary()。反正這里包含了我們傳進(jìn)來的路由信息。保存在RouteCollection集合里面。 提一下: RouteTable 里也一個(gè)RouteCollection,靜態(tài)的,是為了能夠在整個(gè)生命周期里面使用到路由數(shù)據(jù)。如下圖:接著我們繼續(xù)看第二部分吧。2、 在第一部分里,已經(jīng)將MvcRouteHandler添加到了rou

9、teData里面,返回一個(gè)data對(duì)象。而MvcRouteHandler最后傳遞為RouteHandler。第二部分:IRouteHandler routeHandler = routeData.RouteHandler;從routeData里面獲取到routeHandler對(duì)象。為什么是IRouteHandler類型呢? 擦,因?yàn)閺腞oute構(gòu)造函數(shù)開始就是IRouteHandler類型定義來接收的接著看第三部分3、 RequestContext requestContext = new RequestContext(context, routeData); context.Request.

10、RequestContext = requestContext;將context對(duì)象和上面拿到的路由數(shù)據(jù)routeData封裝到RequestContext里面,然后賦值給HttpContextBase下的HttpRequestBase的requestContext屬性。也就是將路由數(shù)據(jù)和封裝過的上下文信息再添加到上下文里面。 IHttpHandler httpHandler = routeHandler.GetHttpHandler(requestContext);GetHttpHandler(requestContext) 這里返回一個(gè)MvcHandler。然后我們?nèi)vcHandler下

11、去看看,還是不看先,留到后面看吧。應(yīng)該就是調(diào)用PR方法執(zhí)行后面一系列流程了。留待后面揭秘。 暫時(shí)知道GetHttpHandler方法里返回這個(gè)MvcHandler對(duì)象就行了。 接收類型是IhttpHandler接口!熟悉啦接著看第四部分,也是在第七個(gè)事件里注冊(cè)的方法執(zhí)行的最后一步。context.RemapHandler(httpHandler);這個(gè)方法是把獲得的那個(gè)MvcHandler添加到上下文對(duì)象中。這個(gè)方法具體做啥先。先得說一下,在第三部分的時(shí)候,已經(jīng)將context傳進(jìn)了HttpContextBase里。待會(huì)用到HttpContextWrapper,它繼承HttpContextBa

12、se,重寫了HttpContextBase里面的ReMapHandler方法。詳細(xì)見圖:好了,進(jìn)入ReMapHandler方法:Type type = handler.GetType();/獲得類型:MvcHandlerhandlerType = type.AssemblyQualifiedName;/獲得當(dāng)前類型在程序集里面的名字:System.web.MVC.MvcHandlerhandlerName = type.FullName;/獲得全名this._remapHandler = handler;/將MvcHandler添加到上下文對(duì)象中,這里的this就是HttpContext在第七

13、個(gè)事件里注冊(cè)的方法,最終就是拿到路由數(shù)據(jù),將創(chuàng)建的Handler添加到上下文中。PostResolveRequestCache(HttpContextBase context)到此,運(yùn)行完接著深入。在原來的ASP.NET 的整個(gè)運(yùn)行周期上,挑中合適的時(shí)機(jī),弄出分叉來,然后MVC.net誕生了。那么這個(gè)時(shí)機(jī)在哪里呢?1、 FrameWork 4.0下會(huì)先讀取系統(tǒng)配置文件,這個(gè)文件下的節(jié)點(diǎn)HttpModules里配置了一個(gè)UrlRoutingModule,在讀取這個(gè)配置文件的時(shí)候,就會(huì)創(chuàng)建這個(gè)Module對(duì)象,創(chuàng)建方法,在初始化的時(shí)候在第七個(gè)事件PostResolveRequestCache里注冊(cè)

14、方法,這個(gè)方法里面封裝上下文和路由信息,創(chuàng)建了MvcHandler 并添加到上了下文里(HttpContex)。2、 在第八個(gè)事件(PostMapRequestHandler)執(zhí)行時(shí)(是不是在執(zhí)行的時(shí)候檢查呢?還是在執(zhí)行之前檢查?這個(gè)還沒有考證!),會(huì)先判斷上面的那個(gè)_remapHandler 是不是空的,如果不空(MVC執(zhí)行程序),就不再創(chuàng)建頁面類對(duì)象,直接返回Handler。否則根據(jù)請(qǐng)求路徑創(chuàng)建頁面類對(duì)象等執(zhí)行ASP.NET運(yùn)行機(jī)制。以上兩個(gè)時(shí)機(jī)造就了MVC。在創(chuàng)建的MvcHandler里有我們最常見的PR(ProcessRequest)方法.現(xiàn)在開始揭秘MvcHandler到底干了什么。

15、(只研究主要的)在ASP.net整個(gè)運(yùn)行的管道第九個(gè)事件里要拿到請(qǐng)求的Session,會(huì)檢查當(dāng)前請(qǐng)求的類是否實(shí)現(xiàn)了IRequiresSessionState接口。再看MvcHandler類,它已經(jīng)實(shí)現(xiàn)了這個(gè)接口!其實(shí),這個(gè)MvcHandler就相當(dāng)于是一個(gè)頁面類對(duì)象。可以自己去該類下面看看。跟ASP.NET一樣,在第十一和十二個(gè)事件之間會(huì)調(diào)用頁面類對(duì)象的PR方法,ASP.NET里調(diào)用page(繼承自IHttpHandler)類的PR(是實(shí)現(xiàn)IHttpHandler的)方法。在Mvc.Net里則調(diào)用MvcHandler(也繼承自IHttpHandler)里的PR(也是實(shí)現(xiàn)IHttpHandler

16、的)方法。老樣子,進(jìn)入PR方法:1、創(chuàng)建一個(gè)控制器接口對(duì)象,在初始化的時(shí)候?yàn)槠滟x值。創(chuàng)建控制器!根據(jù)拿到的控制器的類型,創(chuàng)建的行為是由工廠完成的!工廠在這里起到的作用除了提供多態(tài)外,還提供一個(gè)對(duì)象池,每一次創(chuàng)建控制器的時(shí)候都會(huì)到這個(gè)池里面去檢查。在ProcessRequestInit()方法里面:接著走下去,看CreateController()方法。不做太多的解釋了,到Create()方法,再到Activitor下的CreateInstance方法。反正最終就是根據(jù)type創(chuàng)建出這個(gè)實(shí)例。見下面兩個(gè)圖:2、執(zhí)行Execute()方法,這是一個(gè)很關(guān)鍵的方法。在Initialize方法里:(th

17、is就是ControllerBase)主要看ExecuteCore()方法:好啦,走到這里終于到了調(diào)用Action了。在Action里面會(huì)存在一些與視圖相關(guān)的東西。因此在action里面要?jiǎng)?chuàng)建視圖(View()方法),設(shè)置數(shù)據(jù),返回ViewResult從讀取配置文件在第七個(gè)事件里注冊(cè)方法,創(chuàng)建MvcHandler,將路由信息和請(qǐng)求上下文信息傳進(jìn)去MvcHandler為類頁面類對(duì)象,調(diào)用里面的PR方法,通過反射創(chuàng)建controller對(duì)象,調(diào)用里面的Action。Action就是我們平時(shí)直接寫代碼的方法。返回一個(gè)ActionResult return View();So接下來研究Action,是怎么創(chuàng)建視圖返回的,又是怎樣設(shè)置保存后臺(tái)數(shù)據(jù)等等1、 執(zhí)行程序員的action方法,返回ActionResult:ViewResult就是authContext.Result。這些數(shù)據(jù)保存到HomeController的父類的父類ControllerBase里面,然后再在Controller類里面new了一個(gè)ViewResult,執(zhí)行action的時(shí)候就返回這個(gè)ViewResult,將這些數(shù)據(jù)傳遞保存到ViewResultBase里面,以供創(chuàng)建視圖的時(shí)候使用!2、 拿到ViewResult并保存到AuthContext里面(authContext.Result),開始

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論