ASP.Net內部處理機制

1、IIS服務器根據請求的文件的後綴名來肯定如何處理這個請求。例如.html,或.js,或.aspx…服務器獲取所請求的頁面的後綴名後,在服務器端尋找能夠處理這類後綴名的應用程序,若是IIS找不到能夠處理此類文件的應用程序,而且這個文件也沒有受到服務器端的保護(一個受保護的例子就是App_Code中的文件,一個不受保護的例子就是你的js腳本),那麼IIS就直接把這個文件返回給客戶端。html

 

若是服務器找到了處理此類文件的應用程序,一般稱爲ISAPI(Internet Server Application Programe Interface,互聯網服務器應用程序接口)應用程序,他實際上只是一個接口,起到一個代理的做用,它的主要工做是映射所請求的頁面(文件)和與此後綴名相對應的實際的處理程序。程序員

 

例如全部的.aspx文件實際上都是由aspnet_isapi.dll這個程序來處理的,當IIS把對於.aspx頁面的請求提交給了aspnet_isapi.dll之後,它就再也不關心這個請求隨後是如何處理的了。Asp.net只是服務器(IIS)的一個組成部分而已,它是一個ISAPI擴展。web

 

HttpRuntime類是asp.net的一個主要入口,它有一個稱做ProcessRequest的方法,這個方法以一個HttpWorkerRequest類做爲參數,HttpRuntime類幾乎包含着關於單個Http請求的全部信息:所請求的文件、服務器變量、QueryString、Http頭信息等等。Asp.net使用這些信息來加載、運行正確的文件,而且將這個請求轉換到輸出流中,通常來講,也就是HTML頁面。api

 

當web.config文件的內容發生改變,或者.aspx文件發生變更的時候,爲了可以卸載運行在同一個進程中的應用程序,而後再從新加載,Http請求被分放在相互隔離的應用程序域中。HTTP.SYS的內置驅動程序來監聽來自外部的HTTP請求,在操做系統啓動的時候,IIS首先在HTTP.SYS中註冊本身的虛擬路徑。瀏覽器

 

若是請求是一個可訪問的URL,HTTP.SYS會將這個請求交給IIS工做者進程。IIS6.0中叫作w3wp.exe,IIS5.0中叫作aspnet_wp.exe。服務器

 

除了映射文件與其對應的處理程序外,ISAPI還須要作一些其餘的工做:app

一、從HTTP.SYS中獲取當前的Http請求信息,而且將這些信息保存到HttpWorkerRequest類中。asp.net

二、在相互隔離的應用程序域AppDomain中加載HttpRuntimepost

三、調用 HttpRuntime的ProcessRequest方法。url

接下來纔是程序員一般編寫的代碼所完成的工做了,而後,IIS接收返回的數據流,並從新返還給 HTTP.SYS,最後,HTTP.SYS 再將這些數據返回給客戶端瀏覽器。

 

2、當Http請求進入Asp.net RunTime之後,它的管道由託管模塊(Managed Modules)和處理程序(Handlers)組成,而且由管道來處理這個Http請求。

 

按照圖中的編號瞭解數據是如何流動的:

① HttpRuntime將Http請求轉交給HttpApplication,HttpApplication表明着程序員建立的Web應用程序。HttpApplication建立針對此Http請求的HttpContext對象,這些HttpContext對象包含了關於此請求的諸多其餘對象,主要有HttpRequest、HttpResponse、HttpSessionState等。這些對象在程序中能夠經過Page類或者Context類進行訪問。

② 接下來Http請求經過一系列Module,這些Module對Http請求具備徹底的控制權這些Module能夠作一些執行某個實際工做前的事情

③ Http請求通過全部的Module以後,它會被HttpHandler處理。

④ HttpHandler處理完之後,Http請求再一次回到Module,此時Module能夠作一些某個工做已經完成了以後的事情。

3、Http管道中有兩個可用的接口。一個是IHttpHandler,一個是IHttpModule。經過查看「處理程序映射」,發現好多文件都交給aspnet_isapi.dll去處理了。很明顯,aspnet_isapi.dll不可能對每種文件採用同一種方式處理,因此在C:、WiNDOWS\Microsoft.NET\Framework\v2.0.50727\Config\目錄下web.config文件中的<httpHandlers>節點中將不一樣的文件類型映射給不一樣的Handler去處理,對於.aspx來講,是由System.Web.UI.Page.HandlerFactory來處理。

 1 <httpHandlers>
 2 
 3  ……  4 
 5             <add path="*.aspx" verb="*" type="System.Web.UI.PageHandlerFactory" validate="True" />
 6 
 7             <add path="*.ashx" verb="*" type="System.Web.UI.SimpleHandlerFactory" validate="True" />
 8 
 9             <add path="*.asmx" verb="*" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="False" />
10 
11             <add path="*.rem" verb="*" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory, System.Runtime.Remoting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" validate="False" />
12 
13             <add path="*.soap" verb="*" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory, System.Runtime.Remoting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" validate="False" />
14 
15             <add path="*.asax" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
16 
17             <add path="*.ascx" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
18 
19             <add path="*.master" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
20 
21  …… 22 
23             <add path="*" verb="GET,HEAD,POST" type="System.Web.DefaultHttpHandler" validate="True" />
24 
25             <add path="*" verb="*" type="System.Web.HttpMethodNotAllowedHandler" validate="True" />
26 
27 </httpHandlers>

 

 

.Net Framework在處理Http請求時採用默認Handler,而若是要操控一個Http請求,就須要實現IHTTPHandler接口,而實現IHttpHandler接口的類就是通常處理程序。

 1 // 摘要:  2 
 3     // 定義 ASP.NET 爲使用自定義 HTTP 處理程序同步處理 HTTP Web 請求而實現的協定。
 4 
 5     public interface IHttpHandler  6 
 7  {  8 
 9        bool IsReusable { get; } 10 
11        void ProcessRequest(HttpContext context); 12 
13  }

 

該接口中包含一個屬性和一個方法,其中ProcessRequest方法中的代碼是處理請求的主要代碼。IsReusable屬性,該值指示其餘請求是否可使用IHttpHandler實例,也就是說後繼的Http請求是否是能夠繼續使用實現了該接口的類的實例,爲true時能夠,不然不能夠。下面是一個自定義的處理程序:

 1 public class Handler1 : IHttpHandler  2  {  3         public void ProcessRequest(HttpContext context)  4  {  5             //處理請求的代碼
 6  }  7         public bool IsReusable  8  {  9             get
10  { 11                 return true; 12  } 13  } 14 }

 

 

建立一個自定義的HttpHandler後,爲了讓它可以處理某些HTTP請求,還須要將它註冊到web.config中:

1 <httpHandlers>
2 
3         <add verb="*" path="*.jpg" type="Test_js.Handler1"/>
4 
5 </httpHandlers>

 

path:指的是請求的文件名稱,可使用通配符擴大範圍,也能夠明確指定這個Handler僅用於處理某個特定的文件的請求。

verb:指的是請求此文件的方式,可使post或get,用*表明全部的訪問方式。

type:程序集.類名

IHttpFactory接口概述:

    

1 public interface IHttpHandlerFactory 2 
3  { 4 
5         IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated); 6 
7         void ReleaseHandler(IHttpHandler handler); 8 
9   }

 

GetHandler方法中的參數介紹:

context:System.Web.HttpContext 類的實例,它提供對用於爲 HTTP 請求提供服務的內部服務器對象(如 Request、Response、Session和 Server)的引用。

requestType:客戶端使用的 HTTP 數據傳輸方法(GET 或 POST)。

url:所請求資源的 System.Web.HttpRequest.RawUrl。

pathTranslated:所請求資源的 System.Web.HttpRequest.PhysicalApplicationPath。

 

該接口中定義了2個方法,GetHandler方法在請求開始的時候被調用,而ReleaseHandler在請求結束,全部的Handler都不在須要的時候被調用。

一個HandlerFactory能夠處理N個HttpHandler,何時該處理什麼HttpHandler就在這裏的處理邏輯中實現。

 

何時使用IHttpHandlerFactory:

一、在一個項目中須要使用不少IHttpHandler的時候,並且對這些IHttpHandler判斷都重複作一個一樣的前期處理。

二、從部署和鬆散耦合考慮,若是你的web application足夠大,你就要考慮在更換HttpHandler處理類的時候該不應去改動Web.config的配置,這種改動將會從新啓動整個app,對於一些系統而言這是不能夠隨便進行的。這個時候,統一一個入口的IHttpHandlerFactory很重要,這個入口相對不變,而IHttpHandler實現能夠經過外掛自定義的xml文件來實現鬆散耦合,運用一些反射什麼的就能夠實現了。

3、HttpModule是實現了IHttpModule接口的程序集,HttpModule的做用是與應用程序事件相關的。

    

1 public interface IHttpModule 2 
3  { 4 
5         void Dispose(); 6 
7         void Init(HttpApplication context); 8 
9 }

 

Init()方法:這個方法接受一個HttpApplication對象,HttpApplication表明了當前的應用程序,在這個方法中註冊對事件進行註冊。

Dispose():它能夠在進行垃圾回收以前進行一些清理工做。

經過在Http請求管道中註冊指望對應用程序事件做出反應的方法,在相應的事件觸發的時候,便會調用HttpModule註冊了的方法,實際的工做在這些方法中執行。

 

自定義的HttpModule須要咱們本身在web.config文件中對其進行註冊:

 

1 <system.webServer>
2     <modules>
3       <add name="MyModule" type="WebApplication1.ModuleDemo,WebApplication1"/>
4     </modules>
5   </system.webServer>

 

 

 

整個過程:

一、當站點第一個資源被訪問的時候,Asp.Net會建立HttpApplication類的實例,它表明着站點應用程序,同時會建立全部在Web.Config中註冊過的Module實例。

二、在建立Module實例的時候會調用Module的Init()方法。

三、在Init()方法內,對想要做出響應的HttpApplication暴露出的事件進行註冊。(僅僅進行方法的簡單註冊,實際的方法須要另寫)。

四、HttpApplication在其應用程序週期中觸發各種事件。

五、觸發事件的時候調用Module在其Init()方法中註冊過的方法

相關文章
相關標籤/搜索