承上章,自訂 IHttpModule 的 Init 方法中可掛載管線事件,例如:
public class Test : IHttpModule {
public void Init(HttpApplication context) {
context.BeginRequest += new EventHandler(context_BeginRequest);
context.AuthenticateRequest += new EventHandler(context_AuthenticateRequest);
}
// ... 事件處理方法
}
這些事件在 Pipeline 中如何依序執行?先看 HttpApplication 如何暴露事件:
public event EventHandler BeginRequest {
add { AddSyncEventHookup(EventBeginRequest, value, RequestNotification.BeginRequest); }
remove { RemoveSyncEventHookup(EventBeginRequest, value, RequestNotification.BeginRequest); }
}
public event EventHandler AuthenticateRequest {
add { AddSyncEventHookup(EventAuthenticateRequest, value, RequestNotification.AuthenticateRequest); }
remove { RemoveSyncEventHookup(EventAuthenticateRequest, value, RequestNotification.AuthenticateRequest); }
}
所有事件皆呼叫 AddSyncEventHookup,第一參數為靜態 object 鍵值(如 EventBeginRequest),第二參數為 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
}
發現 Post* 事件(如 PostAuthenticateRequest)不在列舉中,其 add 多傳遞第四參數 true:
public event EventHandler PostAuthenticateRequest {
add { AddSyncEventHookup(EventPostAuthenticateRequest, value, RequestNotification.AuthenticateRequest, true); }
remove { RemoveSyncEventHookup(EventPostAuthenticateRequest, value, RequestNotification.AuthenticateRequest, true); }
}
這表示 Post* 事件共用相同 RequestNotification 值,但以額外旗標區分「後續」階段。HttpApplication 內部以雜湊表按 RequestNotification 分組儲存事件委派,執行時依階段順序依序呼叫同步與非同步事件。此設計確保事件依標準管線順序(BeginRequest → AuthenticateRequest → PostAuthenticateRequest → ... → EndRequest)精確觸發。