ASP.NET底層的初步認識與理解

來源:互聯網
上載者:User

最近在國外的網站亂走一通,發現一些比較好的文章,收集整理加於自己的理解,作為筆記形式記錄下來,讓以後自己有個回憶。

ASP.NET是一個非常強大的構建Web應用的平台,它提供了極大的靈活性和能力以致於可以用它來構建所有類型的Web應用.絕大多數的人只熟悉高層的架構如WebForms和WebServices-這些都在ASP.NET階層在最高層.在這篇文章中我將會討論ASP.NET的底層機制並解釋請求(request)是怎麼從Web伺服器傳送到ASP.NET運行時然後如何通過ASP.NET管道來處理請求.

ASP.NET是一個請求處理引擎.它接收一個發送過來的請求,把它傳給內部的管道直到終點,作為一個開發人員的你可以在這裡附加一些代碼來處理請求.這個引擎是和HTTP/Web伺服器完全分隔的.事實上,HTTP運行時是一個組件,使你可以擺脫IIS或者任何其他的伺服器程式,將你自己的程式寄宿在內.

運行時提供了一個複雜但同時非常優雅的在管道中路由請求的機制.其中有很多相關的對象,大多數都是可擴充的(通過繼承或者事件介面),在幾乎所有的處理流程上都是如此.所以這個架構具有高度可擴充性.通過這個機制,掛接到非常底層的介面(比如緩衝,認證和授權)都變得可能了.你甚至可以在預先處理或者處理後過濾內容,也可以簡單的將符合特殊標記的請求直接路由你的代碼或者另一個URL上.存在著許多不同的方法來完成同一件事,但是所有這些方法都是可以簡單直接地實現的,同時還提供了靈活性,可以得到最好的效能和開發的簡單性.

整個ASP.NET引擎是完全建立在Managed 程式碼上的,所有的擴充功能也是通過Managed 程式碼擴充來提供的.這是對.NET架構具有構建複雜而且高效的架構的能力的最好的證明.ASP.NET最令人印象深刻的地方是深思熟慮的設計,使得架構非常的容易使用,又能提供掛接到請求處理的幾乎所有部分的能力.

ASP.NET在微軟的平台上就是通過ISAPI擴充來和IIS進行互動的,這個擴充寄宿著.NET運行時和ASP.NET運行時.ISAPI提供了核心的介面,ASP.NET使用非託管的ISAPI代碼通過這個介面來從Web伺服器擷取請求,並發送響應回用戶端.ISAPI提供的內容可以通過通用對象(例如HttpRequest和HttpResponse)來擷取,這些對象通過一個定義良好並有很好訪問性的介面來暴露非管理的資料.

當使用者發送一個URL請求時,在Web伺服器端,IIS5或6,獲得這個請求.在最底層,ASP.NET和IIS通過ISAPI擴充進行互動.在ASP.NET環境中這個請求通常被路由到一個副檔名為.aspx的頁面上,但是這個流程是怎麼工作的完全依賴於處理特定副檔名的HTTP Handler是怎麼實現的.在IIS中.aspx通過’應用程式擴充’(又稱為指令碼映射)被映射到ASP.NET的ISAPI擴充DLL-aspnet_isapi.dll.每一個請求都需要通過一個被註冊到aspnet_isapi.dll的副檔名來觸發ASP.NET(來處理這個請求).

ISAPI是底層的非託管Win32 API.ISAPI定義的介面非常簡單並且是為效能做了最佳化的.它們是非常底層的-處理指標和函數指標表來進行回調-但是它們提供了最底層和面向效率的介面,使開發人員和工具供應商可以用它來掛接到IIS上.因為ISAPI非常底層所以它並不適合來開發應用級的代碼,而且ISAPI傾向於主要被用於橋接介面,向上層工具提供應用伺服器類型的功能.

下面來介紹HttpRuntime,HttpContext,HttpApplication

當一個請求到來時,它被路由到ISAPIRuntime.ProcessRequest()方法.這個方法調用HttpRuntime.ProcessRequest方法,它作一些重要的事情

為請求建立一個新的HttpContext執行個體
擷取一個HttpApplication執行個體
調用HttpApplication.Init()方法來設定管道的事件
Init()方法觸發開始ASP.NET管道處理的HttpApplication.ResumeProcessing()方法

首先一個新的HttpContext對象被建立並用來傳遞ISAPIWorkerRequest,這個上下文在整個請求的生命週期總都是可用的並總可以通過靜態屬性.
HttpContext.Currect來訪問.正像名字所暗示的那樣,HttpContext對象代表了當前活動請求的上下文因為他包含了在請求生命週期中所有典型的你需要訪問的重要對象:Request,Response,Application,Server,Cache.在請求處理的任何時候HttpContext.Current給你訪問所有這些的能力.

HttpContext對象也包含一個非常有用的Items集合,你可以用它來儲存針對特定請求的資料.內容物件在請求周期的開始時被建立,在請求結束時被釋放,所有在Items集合中儲存的資料只在這個特定的請求中可用.一個很好的使用的例子是請求日誌機制,當你通過想通過在Global.asax中掛接Application_BeginRequest和Application_EndRequest方法記錄請求的開始和結束時間(象在列表3中顯示的那樣).HttpContext對你就非常有用了-如果你在請求或頁面處理的不同部分需要資料,你自由的使用它.

protected void Application_BeginRequest(Object sender, EventArgs e)
{
 if (App.Configuration.LogWebRequests)
 {
  Context.Items.Add("WebLog_StartTime",DateTime.Now);
 }
}

protected void Application_EndRequest(Object sender, EventArgs e)
{
 if (App.Configuration.LogWebRequests)
 {
  try
  { 
   TimeSpan Span = DateTime.Now.Subtract((DateTime) Context.Items["WebLog_StartTime"] );
   int MiliSecs = Span.TotalMilliseconds;
   WebRequestLog.Log(App.Configuration.ConnectionString, true, MilliSecs);
  } 
 }
}

HttpApplication

每個請求都被路由到一個HttpApplication對象上.HttpApplicationFactory類根據應用程式的負載為你的ASP.NET應用建立一個HttpApplication對象池並為每個請求分發HttpApplication對象的引用.對象池的大小受machine.config檔案中ProcessModel鍵中的MaxWorkerThreads設定限制.
HttpApplication是你的Web程式的外部封裝器,而且它被映射到在Global.asax裡面定義的類上.它是進入HttpRuntime的第一個進入點.如果你查看Global.asax(或者對應的代碼類)你會發現這個類直接繼承自HttpApplication:
HttpApplication的主要職責是作為Http管道的事件控制器,所以它的介面主要包含的是事件.事件掛接是非常廣泛的,大概包括以下這些:
BeginRequest
AuthenticateRequest
AuthorizeRequest
ResolveRequestCache
AquireRequestState
PreRequestHandlerExecute
PostRequestHandlerExecute
ReleaseRequestState
UpdateRequestCache
EndRequest

HttpModule和HttpHandler兩者都是在HttpApplication.Init()函數調用的一部分中被載入並附加到調用鏈上

httpApplication它本身對發送給應用程式的資料一無所知-它只是一個通過事件來通訊的訊息對象.它觸發事件並通過HttpContext對象來向被調用函數傳遞訊息.實際的當前請求的狀態資料由前面提到的HttpContext對象維護.它提供了所有請求專有的資料並從進入管道開始到結束一直跟隨請求

一旦管道被啟動,HttpApplication開始象圖六那樣一個個的觸發事件.每個事件處理器被觸發,如果事件被掛接,這些處理器將執行它們自己的任務.這個處理的主要任務是最終調用掛接到此特定請求的HttpHandler.處理器(handler)是ASP.NET請求的核心處理機制,通常也是所有應用程式層級的代碼被執行的地方.記住ASP.NET頁面和Web服務架構都是作為HttpHandler實現,這裡也是處理請求的的核心之處.模組(module)趨向於成為一個傳遞給處理器(handler)的內容相關的預先處理或後處理器.ASP.NET中典型的預設處理器包括預先處理的認證,緩衝以及後處理中各種不同的編碼機制.

雖然HttpModule看上去很像ISAPI過濾器,它們都檢查每個通過ASP.NET應用的請求,但是它們只檢查映射到單個特定的ASP.NET應用或虛擬目錄的請求,也就是只能檢查映射到ASP.NET的請求.這樣你可以檢查所有ASPX頁面或者其他任何映射到ASP.NET的副檔名.

實現一個HTTP模組是非常簡單的:你必須實現之包含兩個函數(Init()和Dispose())的IHttpModule介面.傳進來的事件參數中包含指向HTTPApplication對象的引用,這給了你訪問HttpContext對象的能力.在這些方法上你可以掛接到HttpApplication事件上.例如,如果你想掛接AuthenticateRequest事件到一個模組上

 

總的來說w3wp.exe調用.NET類庫進行具體處理,順序如下:ISAPIRuntim, HttpRuntime, HttpApplicationFactory, HttpApplication, HttpModule, HttpHandlerFactory, HttpHandler

有時間再對每個對象正進深入理解.

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.