熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

ASP.NET HTTP運行時組成詳解(下)

2013-11-13 12:22:25  來源: .NET編程 

  HTTP 管道

  ASPNET ISAPI 擴展啟動輔助進程後它將傳遞部分命令行參數輔助進程使用這些參數來執行加載 CLR 前需要執行的任務傳遞的值包括COM 和 DCOM 安全性所要求的身份驗證等級可以使用的命名管道的數量和 IIS 進程標識命名管道的名稱是使用 IIS 進程標識和允許的管道數隨機生成的輔助進程不接收可用管道的名稱但可以接收識別管道名稱所需的信息

  COM 和 DCOM 安全性與 Microsoft? NET Framework 有何關系?實際上CLR 是作為 COM 對象提供的更准確地說CLR 本身不是由 COM 代碼構成的但是指向 CLR 的接口卻是一個 COM 對象因此輔助進程加載 CLR 的方式與加載 COM 對象的方式相同

  當 ASPX 請求遇到 IIS 時Web 服務器將根據選擇的身份驗證模型(匿名WindowsBasic 或 Digest)來分配一個令牌當輔助進程收到要處理的請求時令牌被傳遞到輔助進程請求由輔助進程中的線程獲取該線程從最初獲取傳入請求的 IIS 線程繼承身份令牌在 aspnet_wpexe 中負責處理請求的實際帳戶取決於在特殊的 ASPNET 應用程序中是如何配置模擬的如果模擬被禁用(默認設置)則線程將在輔助進程的帳戶下運行默認情況下該帳戶在 ASPNET 進程模型中為 ASPNET在 IIS 進程模型中為 NETWORKSERVICE這兩個帳戶都是帳戶提供的功能比較有限可以有效抵擋回復性攻擊 (Reverttoself Attack)(回復性攻擊是指將模擬的客戶端的安全性令牌回復到父進程令牌為輔助進程分配弱帳戶可以挫敗此類攻擊

  高度概括起來ASPNET 輔助進程完成的一項主要任務就是將請求交給一系列稱為的 HTTP 管道的托管對象要激活 HTTP 管道可以創建一個 HttpRuntime 類的新實例然後調用其 ProcessRequest 方法如前所述ASPNET 中始終只運行一個輔助進程(除非啟用了 Web Garden 模型)該進程在獨立的 AppDomain 中管理所有的 Web 應用程序每個 AppDomain 都有自己的 HttpRuntime 類實例即管道中的輸入點HttpRuntime 對象初始化一系列有助於實現請求的內部對象Helper 對象包括緩存管理器(Cache 對象)和內部文件系統監視器(用於檢測構成應用程序的源文件的更改)HttpRuntime 為請求創建上下文並用與請求相關的 HTTP 信息填充上下文上下文用 HttpContext 類的實例來表示

  另一個在 HTTP 運行時的設置初期創建的 Helper 對象是文本書寫器用於包含浏覽器的響應文本文本書寫器是 HttpWriter 類的實例此對象對頁面代碼以編程方式發送的文本進行緩存HTTP 運行時被初始化後它將查找實現請求的應用程序對象應用程序對象是 HttpApplication 類的實例該類就是 globalasax 文件背後的類globalasax 在編程時是可選的但在構建結構時是必需的因此如果應用程序中沒有構建類則必須使用默認對象ASPNET 運行時包括幾個中間工廠類可以用來查找並返回有效的 Handler 對象以處理請求整個過程中用到的第一個工廠類是 HttpApplicationFactory它的主要任務是使用 URL 信息來查找 URL 虛擬目錄和匯集的 HttpApplication 對象之間的匹配關系

  應用程序工廠類的行為可以概括為以下幾點

  工廠類維護 HttpApplication 對象池並使用它們來處理應用程序的請求池的壽命與應用程序的壽命相同

  應用程序的第一個請求到達時工廠類提取有關應用程序類型的信息(globalasax 類)設置用於監視更改的文件創建應用程序狀態並觸發 Application_OnStart 事件

  工廠類從池中獲取一個 HttpApplication 實例並將要處理的請求放入實例中如果沒有可用的對象則創建一個新的 HttpApplication 對象要創建 HttpApplication 對象需要先完成 globalasax 應用程序文件的編譯

  HttpApplication 開始處理請求並且只能在完成這個請求後才能處理新的請求如果收到來自同一資源的新請求則由池中的其他對象來處理

  應用程序對象允許所有注冊的 HTTP 模塊對請求進行預處理並找出最適合處理請求的處理程序類型這通過查找請求的 URL 的擴展和配置文件中的信息來完成

  HTTP 處理程序是一些實現 IHttpHandler 接口的類NET Framework 為常見的資源類型提供了一些預定義的處理程序包括 ASPX 頁面和 Web 服務machineconfig 文件中的 <httpHandlers> 部分定義了 HttpApplication 對象必須實例化才能處理特定類型資源的請求的類名如果 Helper 類是一個處理程序工廠GetHandler 方法將確定要使用的處理程序類型這時將從一組類似的對象中獲取適當類型的處理程序並對其進行配置以處理請求

  IHttpHandler 接口提供了兩個方法IsReusable 和 ProcessRequest前者將返回一個布爾值表示處理程序是否可以被匯集(大多數預定義的處理程序都是匯集的但是您可以自行定義每次都需要新實例的處理程序)ProcessRequest 方法包含處理特定類型資源所需的所有邏輯例如ASPX 頁面的處理程序基於以下偽代碼

private void ProcessRequest()
{
// 確定請求是否是回發 (postback)
IsPostBack = DeterminePostBackMode();

// 觸發 ASPX 源代碼的 Page_Init 事件
PageInit();

// 加載 ViewState處理已發送的值
if (IsPostBack) {
LoadPageViewState();
ProcessPostData();
}

// 觸發 ASPX 源代碼的 Page_Load 事件
PageLoad();

// ) 再次處理已發送的值(當
// 動態創建控件時)
// ) 將屬性更改的服務器端事件提升為輸入驅動的
// 控件(即復選框的狀態改變)
// ) 執行與回發事件相關的所有代碼
if (IsPostBack) {
ProcessPostDataSecondTry();
RaiseChangedEvents();
RaisePostBackEvent();
}

// 觸發 ASPX 源代碼的 Page_PreRender 事件
PreRender();

// 將控件的當前狀態保存到 ViewState 中
SavePageViewState();

// 將頁面內容呈現給 HTML
RenderControl(CreateHtmlTextWriter(ResponseOutput));
}

  無論調用的資源類型如何基於 HTTP 處理程序的模型是相同的唯一隨資源類型變化而變化的元素是處理程序HttpApplication 對象負責查找應該使用哪種處理程序來處理請求HttpApplication 對象還負責檢測對動態創建的表示資源的程序集(如 aspx 頁面或 asmx Web 服務)所進行的更改如果檢測到更改應用程序對象將確保編譯並加載所請求的資源的最新來源

  臨時文件和頁面程序集

  要全面了解 ASPNET HTTP 運行時讓我們來分析一下當請求 ASPNET 頁面時文件系統層所發生的變化接下來您將了解由 HTTP 管道的對象管理和監視的一組動態創建的臨時文件

  雖然可以將頁面的核心代碼隔離在代碼背後的 C# 或 Microsoft? Visual Basic? NET 類中但可以將 Web 頁面編寫和部署為 aspx 文本文件對於要顯示為 URL 的頁面來說aspx 文件在應用程序的 Web 空間中必須始終可用aspx 文件的實際內容將確定應用程序對象要加載的程序集(或多個程序集)

  按照設計HttpApplication 對象將查找一個根據請求的 ASPX 文件命名的類如果頁面命名為 sampleaspx則要加載的相應的類名為 ASPsample_aspx應用程序對象在 Web 應用程序的所有程序集文件夾中查找這樣的類這些文件夾包括全局程序集緩存 (GAC)Bin 子文件夾和 Temporary ASPNET Files 文件夾如果未找到這樣的類HTTP 結構將分析 aspx 文件的源代碼創建一個 C# 或 Visual Basic NET 類(具體創建哪種類取決於 aspx 頁面上設置的語言)同時對其進行編譯新創建的程序集的名稱是隨機生成的位於特定於應用程序的子文件夾中路徑如下所示 C:\WINDOWS\MicrosoftNET\Framework\v\Temporary ASPNET Files

  子文件夾 v 特定於 ASPNET 如果您使用的是 ASPNET 子文件夾的版本號會有所不同即子文件夾名為 v再次訪問頁面時程序集就已存在不需要重新創建但是HttpApplication 對象是如何確定特定於頁面的程序集是否存在呢?它每次都要掃描大量文件夾嗎?不並不是這樣

  應用程序對象只查看 Temporary ASPNET Files 文件夾中某個特殊文件夾的內容具體路徑(特定於應用程序的路徑)由 HttpRuntimeCodegenDir 屬性返回如果是第一次訪問 aspx 文件(即還未創建頁面程序集)則該文件夾中就不存在以 ASPX 頁面名稱開頭的 XML 文件例如具有動態程序集的 sampleaspx 頁面應有如下的條目

  sampleaspxXXXXXxml

  XXXXX 占位符是一種散列代碼通過讀取該 XML 文件的內容應用程序對象就可以了解要加載的程序集的名稱以及要在其中獲取的類以下代碼片段是這種 Helper 文件的典型內容包含 ASPsample_aspx 類的程序集的名稱是 mvxvxxr

<preserve assem=mvxvxxr type=ASPsample_aspx
<filedep name=c:\inetpub\wwwroot\vdir\sampleaspx />
</preserve>

  當然只有在分析 filedep 文件的源代碼以生成動態程序集時才創建該文件對 filedep 文件所做的任何更改都會使程序集無效在下一次請求時必須重新編譯需要注意的是在 ASPNET 架構的未來版本中該實現過程可能會有較大改變不論什麼原因只要您決定在當前應用程序中使用它都必須十分小心

  由於更新而要為頁面創建新的程序集時ASPNET 將驗證是否可以刪除舊的程序集如果舊的程序集只包含修改後的頁面的類ASPNET 將試圖刪除並替換該程序集否則將在保留舊程序集的情況下創建一個新程序集

  在刪除過程中ASPNET 可能會發現程序集文件已被加載並鎖定這種情況下可以為舊程序集添加一個DELETE擴展名以將其重新命名(注意所有 Windows 文件都可以在使用過程中重新命名)只要應用程序重新啟動(例如由於對某個應用程序文件如 globalasax 和 webconfig 進行了更改)這些臨時的 DELETE 文件就將被刪除但在處理下一個請求時ASPNET 運行時不會刪除這些文件

  請注意默認情況下在整個應用程序重新啟動之前每個 ASPNET 應用程序最多可以重新編譯 個頁面同時會損失一些會話和應用程序數據當最近的編譯次數超過了 <httpRuntime> 部分的 numRecompilesBeforeAppRestart 屬性中設置的阈值時將卸載 AppDomain並重新啟動應用程序還要注意NET Framework 中您無法卸載單個程序集AppDomain 是可以從 CLR 卸載的最小的代碼塊

  小結

  ASPNET 應用程序有兩大特征進程模型和頁面對象模型ASPNET 提前使用了 IIS 的一些功能而 IIS 則是 Windows Server 中提供的全新的開創性的 Microsoft Web 信息服務尤其值得一提的是在獨立的輔助進程中運行的 ASPNET 應用程序其行為與 IIS 中的所有應用程序相同而且盡管會出現運行時異常內存洩露或程序錯誤ASPNET 運行時仍能自動回收輔助進程以保證實現卓越的性能這種功能已成為 IIS 的系統功能

  在本文中我概括介紹了默認的 ASPNET 進程模型的基礎知識以及 IIS 級代碼(ASPNET ISAPI 擴展)和輔助進程之間的交互同時還介紹了與 IIS 進程模型之間的最新區別


From:http://tw.wingwit.com/Article/program/net/201311/15766.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.