ASP.NET網頁請求以及處理全過程(反編譯工具查看原始碼)

來源:互聯網
上載者:User
 

本文是自己查看源碼後的個人總結,不保證其準確性。大家可作為參考。

瀏覽器和伺服器之間的通訊。

當敲一個網域名稱到瀏覽器上面,然後斷行符號的時候,如:http://www.baidu.com/index.aspx

瀏覽器會按照HTTP協議的文法產生相應的請求報文。

瀏覽器檢查本機是否儲存了http://www.baidu.com/index.aspx網域名稱對應的伺服器IP地址。如果沒有,則發送請求到所在城市網中最近的DNS伺服器(網域名稱解析伺服器),它會根據我們發送來的網域名稱查詢到該網域名稱對應的伺服器IP地址,並發送回瀏覽器。

瀏覽器DNS伺服器獲得了這個網域名稱所對應的伺服器電腦的IP然後在龐大的互連網中找到這個對應的伺服器

HTTP協議規定伺服器軟體如(iis)使用的預設連接埠是80連接埠,也就是說瀏覽器預設的將HTTP請求報文發送到對應伺服器的80連接埠。

 

伺服器接受到瀏覽器發送到的HTTP請求報文(具體報文用httpwatcher查看)。

下面是發送到百度的請求報文:

 

 

伺服器分析請求報文中的路徑和檔案名稱,在伺服器找到這個檔案。

如果是CSS和html,js,圖片等檔案就直接在伺服器上面讀取這個檔案發送給瀏覽

器用戶端。

下面是對ASP.NET動態網頁面的處理

當伺服器IIS發現你請求的頁面是動態網頁面,他發現他自己處理不了。

開啟IIS,會發現裡面有個處理常式映射

 

 

 

,也就是說IIS會將我們的.aspx尾碼的檔案交給對應的處理常式(aspnet_isapi.dll)。這裡簡稱ISAPI。

ISAPI就會將請求交給.NET framework。

再有ISAPI將請求交給ASP.NET,也就是一個名為aspnet_wp.exe的背景工作處理序aspnet_wp.exe就調用FrameWork裡的類 ------- ISAPIRuntime。

下面是用反編譯工具來分析的這個類ISAPIRuntime

 

 

 

 

看到這個方法,就會想到了記憶體回收。

其實這不是重點。重點是

這個processrequest方法

 

點擊這個方法進去

 

 

首先會建立一個ISAPIWorkerRequest的對象wr,將請求報文封裝到wr中

然後調用這個類的CreateWorkerRequest方法執行個體化這個對象

進入這個方法

 

 

這個方法會根據當前的IIS版本建立不同的對象

再回到ProcessRequest方法

 

 

接著就會調用HttpRuntime的ProcessRequestNoDemand方法。將wr傳進去

 

進入這個方法

 

在這個方法的最後會調用

ProcessRequestNow方法。處理請求

這個方法有調用了另一個方法。進去

 

 

這裡就會發現一個熟悉的東西,HttpContext(內容物件)

這個方法會根據上面建立的ISAPIWorkerRequest對象wr(封裝了請求報文)建立HttpContext。如果建立出錯,就會返回一個400的錯誤。

 

 

判斷是否是第一次請求之前

 

 

(如果是第一次請求,就設定當前的時間為第一次請求的起始時間。初始化第一次請求。設定第一次請求為false)

 

初始化Response.

 

當httpwriter為空白的時候,就建立。可以看到,context.response中有2個寫出器

 

一個是httpwriter,一個是textwriter

然後通過HttpApplicationFactory建立一個HttpApplication對象(此對象負責真正處理頁面對象的建立和執行,先在httpapplication池中看又沒有這個對象,沒有就new一個)

下面開啟HttpApplication這個類

 

 

在這裡面最重要的就是這25個事件。其中有19個事件開放給我們使用。

1,BeginRequest

HTTP管道開始處理請求時,會觸發BeginRequest事件

2-3,AuthenticateRequest,PostAuthenticateRequest

ASP.NET先後觸發這兩個事件,使安全模組對請求進行身分識別驗證,。

4-5,AuthorizeRequest,PostAuthorizeRequest

ASP.NET先後觸發這兩個事件,使安全模組對請求進程授權

6-7,ResolveRequestCache,PostResolveRequestCache

 ASP.NET先後觸發這兩個事件,以使緩衝模組利用緩衝的直接對請求直接進程響應(緩衝模組可以將響應內容進程緩衝,對於後續的請求,直接將緩衝的內容返回,從而提高響應能力)。

8,PostMapRequestHandler

 對於訪問不同的資源類型,ASP.NET具有不同的HttpHandler對其進程處理。對於每個請求,ASP.NET會通過副檔名選擇匹配相應的HttpHandler類型,成功匹配後,該實現被觸發

9-10,AcquireRequestState,PostAcquireRequestState

ASP.NET先後觸發這兩個事件,使狀態管理模組擷取基於當前請求相應的狀態,比如SessionState

11-12,PreRequestHandlerExecute,PostRequestHandlerExecute

ASP.NET最終通過一請求資源類型相對應的HttpHandler實現對請求的處理,在實行HttpHandler前後,這兩個實現被先後觸發

13-14,ReleaseRequestState,PostReleaseRequestState

ASP.NET先後觸發這兩個事件,使狀態管理模組釋放基於當前請求相應的狀態

15-16,UpdateRequestCache,PostUpdateRequestCache

 ASP.NET先後觸發這兩個事件,以使緩衝模組將HttpHandler處理請求得到的相應儲存到輸出緩衝中

17-18,LogRequest,PostLogRequest

ASP.NET先後觸發這兩個事件為當前請求進程日誌記錄

19,EndRequest

整個請求處理完成後,EndRequest事件被觸發

在第8個事件建立被請求頁面類的對象,並轉換成Ihttphandler介面類對象。,

在9-10事件中會接受瀏覽器發送過來的sessionid,並且根據此值到伺服器的session池中找到相對應的session對象,並將它賦值給頁面類對象的session屬性。

在第11到12事件之間執行頁面類的processrequest方法。

下面是狀態保持:session,cookie viewstate。寫完狀態保持再仔細將在11到12事件中具體做了什麼事情

Cookie是儲存在瀏覽器端的,cookie有兩種狀態,一種是儲存在用戶端電腦的記憶體中,當訪問頁面的時候建立的cookie(也就是沒有設定到期時間的cookie)。還有一種是設定了到期時間為正的cookie,是儲存在瀏覽器所對應的cookie檔案夾中的。設定cookie前,瀏覽器發送請求到伺服器,伺服器要對該瀏覽器設定cookie,所以就發送一個cookie到瀏覽器,儲存在用戶端的記憶體或者硬碟中。當設定了cookie後,每次請求頁面都會把cookie發送到伺服器

 

伺服器通過讀取cookie得知你的相關資訊然後進行相應的操作。

Session是依賴於cookie實現的。不同的是session是儲存在伺服器端的。

例如,當我們登陸的時候,伺服器那邊會給我們設定一個session儲存在伺服器端,然後會產生一個sessionid發送到瀏覽器端,瀏覽器這邊儲存這個sessionid,當你再請求別的頁面的時候,瀏覽器就會將這個sessionid發送到伺服器。,伺服器根據從瀏覽器發送過來的sessionid自動從伺服器的session池中找到與這個sessionid想對應的session對象並賦值給當前頁面對象的session屬性。

如果瀏覽器禁用了Cookie的話,那伺服器也可以通過將sessionId儲存在url中來完成sessionid在瀏覽器和伺服器間的傳遞。(需要設定設定檔裡的sessionState節點的 cookieless="autodetect")

<sessionState cookieless="AutoDetect"></sessionState>

Viewstate:頁面的viewstate屬性實際上就是擷取了瀏覽器提交過來的一個名位__VIEWSTATE的隱藏欄位裡面的值。

使用viewstate必須要有一個runat=“server”的表單

在頁面類對象執行processrequest方法的時候,先建立控制項樹,然後通過執行loadstate方法,將請求報文中的名為__VIEWSTATE反base64編碼然後進行序列化,最終還還原成集合,再將其中屬於程式員自己添加的viewstate裡面的索引值對還原到頁面對象的viewstate屬性中,然後再執行page_load。,然後執行savestate將資料儲存到viewstate屬性中。

 

那麼在第11到12之間中執行了頁面類對象的processrequest方法,到底做了什麼呢 。

1,  調用父類的processrequest方法,在此方法中父類調用父類的FrameworkInitialize()方法,但因為被頁面類重寫了,所以執行的是當前頁面類的FrameworkInitialize()方法。在中間調用了_buildControlTree

2,  打造控制項樹

前台頁面類。

前台頁面類繼承自後台頁面類。

 

 

後台頁面類繼承自page

 

 

 

 

 

 

Templatecontrol繼承自control

 

 

 

在coltrol類中

 

 

在中間有一個control集合

 

 

也就是說我們的前台頁面類根據繼承關係包含了一個控制項集合。

再來到前台頁面類。

,在最後面發現一個ProcessRequest方法。

 

 

,進去。

 

 

Bulidcontroltree開始打造控制項樹。

 

 

前台類繼承後台類

litralControl包含html代碼的第一段。

Htmlhead-htmltitle......

 

 

 

 

 

_BuildControlTree這個方法會將前台的所有代碼封裝起來,根據不同的標籤封裝成不同的控制項對象。

 

 

 

3,  執行頁面生命週期

1. Page_Init();
2. Load ViewState and Postback data;
3. Page_Load();
4. Handle control events;
5. Page_PreRender();
6. Page_Render();
7. Unload event;
8. Dispose method called;

階段

說明

頁請求

頁請求發生在頁生命週期開始之前。使用者請求頁時,ASP.NET 將確定是否需要分析和編譯頁(從而開始頁的生命週期),或者是否可以在不運行頁的情況下發送頁的緩衝版本以進行響應。

開始

在開始階段,將設定頁屬性,如 Request 和 Response。在此階段,頁還將確定請求是回傳請求還是新請求,並設定 IsPostBack 屬性。此外,在開始階段期間,還將設定頁的 UICulture 屬性。

頁初始化

頁初始化期間,可以使用頁中的控制項,並將設定每個控制項的 UniqueID 屬性。此外,任何主題都將應用於頁。如果當前請求是回傳請求,則回傳資料尚未載入,並且控制項屬性值尚未還原為檢視狀態中的值。

載入

載入期間,如果當前請求是回傳請求,則將使用從檢視狀態和控制項狀態恢複的資訊載入控制項屬性。

驗證

在驗證期間,將調用所有驗證程式控制項的 Validate 方法,此方法將設定各個驗證程式控制項和頁的 IsValid 屬性。

回傳事件處理

如果請求是回傳請求,則將調用所有事件處理常式。

呈現

在呈現之前,會針對該頁和所有控制項儲存檢視狀態。在呈現階段中,頁會針對每個控制項調用 Render 方法,它會提供一個文本編寫器,用於將控制項的輸出寫入頁的 Response 屬性的 OutputStream 中。

卸載

完全呈現頁並已將頁發送至用戶端、準備丟棄該頁後,將調用卸載。此時,將卸載頁屬性(如 Response 和 Request)並執行清理。

 

4,  調用頁面類的Render方法產生html代碼。

 

上面貌似很亂 。下面整理一下。

1,  瀏覽器請求一個動態網頁面。IIS發現自己不能處理,將請求轉給映射表。

2,  對應程式裡面aspx頁面對應的是aspnet_isapi.dll,於是就將請求轉給ISAPI

3,  請求報文通過ISAPIRuntime交給了HttpRuntime。

4,  在HttpRuntime裡面建立了ISAPIWorkerRequest的對象wr,將請求報文封裝到wr中。再通過一系列方法建立HttpContext內容物件,裡麵包含HttpRequest和HttpResponse。

5,  然後通過HttpApplicationFactory建立一個HttpApplication對象(此對象負責真正處理頁面對象的建立和執行,先在httpapplication池中看又沒有這個對象,沒有就new一個)

6,  在httpapplication請求管道中調用19個標準的處理事件。

在第8個事件中建立被請求的頁面類對象

在第9-10事件中接受瀏覽器發送過來的sessionid,並且根據此值到伺服器的session池           中找到相對應的session對象,並將它賦值給頁面類對象的session屬性。

第11-12事件執行頁面類的processrequest方法。打造控制項樹,執行頁面生命週期,調用頁面類中所有控制項對象的Render方法,產生html代碼

7,  將html代碼返回給瀏覽器。

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.