從Asp .net到Asp core (第一篇)《回顧Asp .net生命周期與管道機制》


從2016年微軟收購了Xamarin整合到Visual Studio里並將其開源到現在已有三年多時間,從.net core 1.0 到現在的2.2,以及即將問世的3.0,我們看到微軟正在跨平台之路越走越遠,從之前的偏科學生變成了現在的三號學生,希望以為以后還會越來越好

作為微軟的狂熱粉,從17年底就開始熱衷於.net core 的學習和使用,下面談談我對web 框架asp core的簡單理解

1:首先第一個問題.net core和Asp core有什么區別?是同一個東西嗎?

  .net core是一個統一的平台,是微軟准備要用來開發移動端,桌面應用,web網站等的整體平台

  asp core 是.net core着重開發網站的web 框架,這也就就好比之前.net框架與Aps .net框架的關系,可以理解為包含關系吧

2:Asp core與原來的Asp .net框架有什么區別,它對比傳統Asp .net框架到底有哪些好處?

  首先我想說,Asp core其實對比原來的Asp .net,其實可以說完全是一套新的東西(並不像之前Asp .net到Asp .net MVC,Asp .net MVC只是在原有的Asp .net框架擴展和升級,其本質還是.net框架的那一套)。

但是Asp core雖說是一套新的框架,聽到說是新的東西也不要緊張,個人感覺Asp core很多基礎開發的用法,還是保留了原來.net開發人員的一些開發習慣,實際開發過程中個人的感覺沒有給人一種陌生的感覺

  對比Asp core與Asp .net的區別:

  • 首先一條Asp core是跨平台的,何為跨平台,就是Asp core可以部署和運行在windows以外的其他服務器上面(當然必須要在所要運行的系統上安裝有運行時,好比java的JRE)比如更適合做服務器系統的linux服務器,而且並不像之前的Aps .net完全依賴IIS,新的Asp core可以部署到IIS,Nginx,Apache等其他代理服務器
  • 新的Asp.net core默認使用Kestrel作為Http請求的監聽器,而並不依賴原先龐大復雜的Https.sys。Kestrel不僅僅是微軟下一代的跨平台Http請求監聽器,同時還提供了比Https.sys更輕量級以及更快速的Http請求處理。
  • Asp.net core與原來的Web設計另一個最大的區別在於Asp.net core(及.net core),完全拋棄了原來的使用管道模式來接收以及處理HttpRequest。在Asp.net core中允許處理中間件(Middleware)來對所有的HttpRequest來進行請求,當請求被接收到時,Asp.net core會調用注冊的中間件(按照注冊的順序)對HttpRequest進行處理。這樣做相比與原來使用HttpApplication的管道方式而言,其優勢在於完全由開發人員決定HttpRequest需要執行怎么樣的處理,沒有多余的其他步驟。而原來的方式既使開發人員不希望對一個HttpRequest進行任何處理,但HttpApplication仍然會按照管道的設置依次創建HttpModel -> 激活HttpHandler -> 處理Session等。相對原來的Aps .net程序,程序性能也有很大的提升

3:傳統的asp .net框架請求處理流程

  3.1 IIS服務器請求處理流程

  1,當IIS服務器接收到一個 Http請求的時候,對於IIS來說,它依賴一個叫做 HTTP.SYS 的內置驅動程序來監聽來自外部的 HTTP請求。

  在操作系統啟動的時候,IIS首先在HTTP.SYS中注冊自己的虛擬路徑。實際上相當於告訴HTTP.SYS哪些URL是可以訪問的,哪些是不可以訪問的(舉個簡單的例子:為什么你訪問不存在的文件會出現 404 錯誤呢?就是在這一步確定的)。

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

  每個工作者進程都有一個身份標識 以及 一系列的可選性能參數(是指諸如 回收機制的設置、超時時間設置 等等)。

  2,然后請求會首傳遞到ISAPI(Internet Server Application Programe Interface,互聯網服務器應用程序接口),ISAPI決定如何去處理這個請求,如果服務器獲取所請求的靜態文件(也可以是文件,比如 jimmy.jpg)的后綴名之后,接下來會在服務器端尋找可以處理這類后綴名的應用程序,如果IIS找不到可以處理此類文件的應用程序,並且這個文件也沒有受到服務器端的保護(比如代碼文件,配置文件.config都是受保護的, 不受保護的比如js,css),那么IIS將直接把這個文件返還給客戶端。

ISAPI是什么?到底長啥樣?

ISAPI 服務器擴展是可以被 HTTP 服務器加載和調用的 DLL(動態鏈接庫)

如圖:

  3,然后ISAPI 還需調用 HttpRuntime的ProcessRequest方法,開始進入請求管道周期,請求最終走完整個管道周期,ISAPI 接收返回的數據流,並重新返還給 HTTP.SYS,最后,HTTP.SYS 再將這些數據返回給客戶端瀏覽器。

上面文字總結可能有些枯燥,下面這張圖片也許會清晰許多

 流程:請求開始=>Http.Sys=>ISAPI=>CLR/HttpRuntime=>ISAPI=>Http.Sys=>請求結束

  3.2 理解管道

  前面講到請求在IIS中的一個簡單流程,但是講到當請求進入asp.net Runtime之后的細節,只是一筆帶過,沒有將請求在asp.net Runtime中到底經過了哪些處理,最終又是如何返回請求結果的,下面就來簡單講解一下整個過程

  這里會是涉及到在.net框架兩個比較重要的概念:Http Module和 Http Handler

  想要理解這兩個概念,首先要知道當請求進入asp.net Runtime之后會經歷如下圖的十九個事件

對於這個事件要廢話幾句,這個流程雖然看着比較多,對於初學者其實不要有太大壓力,其實完全沒必要去每一個都研究他,只是大概過一遍,知道有這么個東西,混個眼熟就好了

Http Module 托管模塊

如果我們想要在上面某一個事件中去處理我們自己框架代碼,比如要在請求到達某個事件時我們要對該請求進行篩選或者在此時記錄一條日志,我們應該怎么做?

這里就需要用到Http Module了,我們可以通過Http Module在Http請求管道(Pipeline)中注冊期望對應用程序事件做出反應的方法

Http Module實現了IHttpModule接口,IHttpModule接口要是實現Dispose和Init方法

Dispose:它可以在進行垃圾回收之前進行一些清理工作。

Init:我們可以在init方法中注冊上面十九個事件的任意一個或者多個,並在對應的回調方法中去做實際的邏輯處理

具體代碼如下:

    public class TestModule : IHttpModule
    {
        void IHttpModule.Dispose()
        {
        }

        void IHttpModule.Init(HttpApplication context)
        {
            context.EndRequest += new EventHandler(context_EndRequest);
        }

        private void context_EndRequest(object sender, EventArgs e)
        {
            /*HttpApplication對象包含了請求所需要的所有上下文對象,比如HttpContext,HttpRequest,HttpResponse,HttpSession等等,所以我們可以通過這個對象
             來完成過濾請求,記錄日志等等實際開發中會用到的功能
             */
            HttpApplication application = (HttpApplication)sender;

            HttpContext context = application.Context;
            context.Response.Write("<hr><h1 style='color:#f00'>來自HttpModule的處理,請求結束</h1>");
        }
    }

值得注意的是Http Module所處理的請求通常是全局的,應用級別的,不是只針對哪一個頁面,什么意思,比如把上面代碼作為的例子,上面代碼的效果會使所有的頁面都會有 “來自HttpModule的處理,請求結束”,這句話

Http Handler 處理程序

對比Http Module,HttpHandler的處理請求的權限相對較低,維度也更細,它可以只針對特定后綴的頁面,其實我們的webform頁面其實也就是一個Handler

所有aspx頁面繼承System.Web.UI.Page,可以看到Page類也實現了IHttpHandler接口

public interface IHttpHandler{
    void ProcessRequest(HttpContext context);
    bool IsReusable { get; }
}
  • ProcessRequest 用來處理請求的主要代碼。
  • IsReusable 屬性,MSDN上是這樣解釋的:獲取一個值,該值指示其他請求是否可以使用 IHttpHandler 實例。也就是說后繼的Http請求是不是可以繼續使用實現了該接口的類的實例,一般來說,我把它設置成true。

 我們HttpHandler用的比較多的場景就是有Ajax+Httphandler進行web無刷新頁面開發,然后就是HttpHandler實現圖片防盜鏈,IhttpHandler實現圖片驗證碼等等,傳統的Http Module和HttpHandler編寫程序,其實都是比較老的開發方式了,個人感覺只需要學習和了解.net有這兩個東西就好了

經過上面基礎的學習,我們來總計一下進入asp.net Runtime之后,和Http Module和HttpHandler發生了哪些關系,梳理出一個流程

  1. 請求進入HttpRuntime
  2. HttpRuntime 通過HttpApplicationFactory 創建 HttpApplication對象(HttpApplication代表着程序員創建的Web應用程序。HttpApplication創建針對此Http請求的 HttpContext對象,這些對象包含了關於此請求的諸多其他對象如HttpRequest、HttpResponse、HttpSessionState)
  3. 接下來Http請求通過一系列Module對請求進行應用級別的處理
  4. Http Module處理完成后會把請求轉交給HttpHandler去進行一些定制化的頁面級別的處理
  5. HttpHandler在處理完成后又會轉回Http Module做一些后續的收尾處理

 以上就是整個Asp.Net的生命周期,雖然在這之后,出現了Asp.Net MVC,正如前面所說,但是Asp.Net MVC框架並不是一套新的框架,Asp.net Mvc還是以Asp.net運行時為基礎的。但是Asp Core並不再以Asp.netRuntime為基礎的,所以它也沒有了十九個事件,也沒有了Http Module和HttpHandler這一套,但是Asp Core引入了一些新的核心概念如中間件(middleware),控制反轉容器(DI)等等,那么我會在下一篇文章簡單解析Asp Core一些相關概念,以及它的的請求周期

 

參考資料:

http://go.microsoft.com/?linkid=8101007

https://docs.microsoft.com/en-us/previous-versions/aspnet/ms227435(v=vs.100)

http://www.tracefact.net/tech/001.html

https://www.cnblogs.com/me-sa/archive/2009/06/01/MVCLifecycle.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM