程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> ASP.NET >> 關於ASP.NET >> MVC系列(5) Http Pipeline詳細分析(下)

MVC系列(5) Http Pipeline詳細分析(下)

編輯:關於ASP.NET

接上面的章節,我們這篇要講解的是Pipeline是執行的各種事件,我們知道,在自定義的HttpModule的Init方法裡,我們可以添加自己的事件,比如如下代碼:

public class Test : IHttpModule  
{  
    public void Init(HttpApplication context)  
    {  
        context.BeginRequest += new EventHandler(context_BeginRequest);  
        context.AuthenticateRequest += new EventHandler(context_AuthenticateRequest);  
    }  
      
    void context_AuthenticateRequest(object sender, EventArgs e)  
    {  
        throw new NotImplementedException();  
    }  
      
    void context_BeginRequest(object sender, EventArgs e)  
    {  
        throw new NotImplementedException();  
    }  
}

然後添加的代碼,在Pipeline裡執行的時候就會把這些事件給執行了,那麼如何執行並且按照什麼順序執行的呢? 在了解這些之前,我們先看看這些事件是如何在HttpApplication裡暴露出來了,添加事件存放在何處的呢?閱讀HttpApplication 的源碼,我們可以看到,所有的事件都是按照如下的形式暴露的,選擇其中兩個看一下:

/// <devdoc><para>[To be supplied.]</para></devdoc>   
public event EventHandler BeginRequest {  
    add { AddSyncEventHookup(EventBeginRequest, value, RequestNotification.BeginRequest); }  
    remove { RemoveSyncEventHookup(EventBeginRequest, value, RequestNotification.BeginRequest); }  
}   
      
       
/// <devdoc><para>[To be supplied.]</para></devdoc>   
public event EventHandler AuthenticateRequest {  
    add { AddSyncEventHookup(EventAuthenticateRequest, value, RequestNotification.AuthenticateRequest); }   
    remove { RemoveSyncEventHookup(EventAuthenticateRequest, value, RequestNotification.AuthenticateRequest); }  
}

可以發現,所有的事件都是調用AddSyncEventHookup方法添加進去的,其中第一個參數是以Event+事件名稱的值,這個值是如何得來的,我們找到聲明的代碼:

private static readonly object EventDisposed = new object();  
private static readonly object EventErrorRecorded = new object();  
private static readonly object EventPreSendRequestHeaders = new object();   
private static readonly object EventPreSendRequestContent = new object();  
       
private static readonly object EventBeginRequest = new object();   
private static readonly object EventAuthenticateRequest = new object();  
private static readonly object EventDefaultAuthentication = new object();   
private static readonly object EventPostAuthenticateRequest = new object();  
private static readonly object EventAuthorizeRequest = new object();  
private static readonly object EventPostAuthorizeRequest = new object();  
private static readonly object EventResolveRequestCache = new object();   
private static readonly object EventPostResolveRequestCache = new object();  
private static readonly object EventMapRequestHandler = new object();   
private static readonly object EventPostMapRequestHandler = new object();   
private static readonly object EventAcquireRequestState = new object();  
private static readonly object EventPostAcquireRequestState = new object();   
private static readonly object EventPreRequestHandlerExecute = new object();  
private static readonly object EventPostRequestHandlerExecute = new object();  
private static readonly object EventReleaseRequestState = new object();  
private static readonly object EventPostReleaseRequestState = new object();   
private static readonly object EventUpdateRequestCache = new object();  
private static readonly object EventPostUpdateRequestCache = new object();   
private static readonly object EventLogRequest = new object();   
private static readonly object EventPostLogRequest = new object();  
private static readonly object EventEndRequest = new object();

再結合add和remove方法,可以大膽猜想,這些值應該是作為key值用的,我們先看完第2個參數,再來驗證我們的猜想,第2個參數是枚舉類型 RequestNotification,這裡我們再猜想一下,所有的事件都應該放在統一的地方,然後用這個枚舉來區分。讓我們先看看這個枚舉類的代碼:

[Flags]  
public enum RequestNotification  
{  
    BeginRequest = 1,  
    AuthenticateRequest = 2,  
    AuthorizeRequest = 4,  
    ResolveRequestCache = 8,  
    MapRequestHandler = 16,  
    AcquireRequestState = 32,  
    PreExecuteRequestHandler = 64,  
    ExecuteRequestHandler = 128,  
    ReleaseRequestState = 256,  
    UpdateRequestCache = 512,  
    LogRequest = 1024,  
    EndRequest = 2048,  
    SendResponse = 536870912,  
}

發現什麼了沒有?雖然使用了Flags標記來記錄以便進行異或查詢,但是這裡的枚舉類型好像少了一些吧,仔細對照代碼發現所有以Post開頭的事件都沒出現在這個枚舉類裡,為什麼呢?那這些事件是如何聲明的?回到HttpApplication類來繼續查看代碼,

/// <devdoc><para>[To be supplied.]</para></devdoc>  
public event EventHandler PostAuthenticateRequest {  
    add { AddSyncEventHookup(EventPostAuthenticateRequest, value, RequestNotification.AuthenticateRequest, true); }   
    remove { RemoveSyncEventHookup(EventPostAuthenticateRequest, value, RequestNotification.AuthenticateRequest, true); }  
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved