處理公用事件
HttpApplication 類別所引發的所有公用事件皆使用 Application_EventName 語法來支援。例如,Error 事件的處理常式可宣告為 protected void Application_Error(Object sender, EventArgs e)
。該語法也同時支援非同步事件。
公用事件有三個分類:HttpApplication 引發的應用程式事件、HttpModule 引發的模組事件和 HTTPApplication 引發的非同步事件。
應用程式事件
下表說明在應用程式存留期間,HttpApplication 所引發的事件。第一個表格說明執行應用程式之前所引發的事件。該事件將以其發生順序列出。
事件 | 說明 |
---|---|
BeginRequest | 表示新的要求:每次要求時都會引發。 |
AuthenticateRequest | 表示該要求已可進行驗證;供安全性模組使用。 |
AuthorizeRequest | 表示該要求已可進行授權;供安全性模組使用。 |
ResolveRequestCache | 供輸出快取模組使用,可縮短已快取的要求的處理時間。 |
AcquireRequestState | 表示應可取得每個要求的狀態。 |
PreRequestHandlerExecute | 表示即將執行該要求處理常式。在呼叫此要求的 HttpHandler 之前,這是最後一個可參與的事件。 |
下表說明傳回應用程式後所引發的事件。該事件將以其發生順序列出。
事件 | 說明 |
---|---|
PostRequestHandlerExecute | 表示 HttpHandler 已完成要求的處理。 |
ReleaseRequestState | 表示應用程式已完成要求作業,因此應該儲存要求狀態。 |
UpdateRequestCache | 表示已完成程式碼的處理,而且檔案已可新增到 ASP.NET 快取中。 |
EndRequest | 表示已完成要求的所有處理作業。這是當應用程式結束後,最後被呼叫的事件。 |
此外,有三種可依非決定性順序來引發的要求事件。下表將分別說明。
事件 | 說明 |
---|---|
PreSendRequestHeaders | 表示 HTTP 標題將傳送到用戶端。它將提供在傳送標題之前,新增、移除或修改標題的機會。 |
PreSendRequestContent | 表示內容即將傳送到用戶端。它提供在傳送內容之前,修改內容的機會。 |
Error | 表示為處理的例外狀況 (Exception)。 |
模組事件
您可以連接到由定義於組態中 HttpModule 所發行的 (攔截) 事件。例如,Machine.config
為所有應用程式宣告下列預設模組。
<httpModules>
<add name="OutputCache" type="System.Web.Caching.OutputCacheModule, .../>
<add name="Session" type="System.Web.SessionState.SessionStateModule, .../>
<add name="WindowsAuthentication" type="System.Web.Security.WindowsAuthenticationModule, .../>
<add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule .../>
<add name="PassportAuthentication" type="System.Web.Security.PassportAuthenticationModule .../>
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule, .../>
<add name="FileAuthorization" type="System.Web.Security.FileAuthorizationModule, .../>
</httpModules>
在所有類別中,尋找它們所定義的公用事件。您可以使用 ModuleName**_OnEvent**Name 語法在 Global.asax 中攔截它們。例如,SessionStateModule 模組的 Start 事件即在 Global.asax 中宣告為 protected void Session_Start(Object sender, EventArgs e)
。您可以使用 ASP.NET 應用程式檔 <script runat=server>
區塊中的 Session_OnStart 語法來定義 SessionStateModule 的 Start 事件,如下所示。
<script language="VB" runat="server">
Sub Session_OnStart()
' Session startup code goes here.
End Sub
</script>
注意 當自訂模組中的事件已宣告於應用程式的配置檔中時,您就可以輕鬆地使用同一個 ModuleName**_On**EventName 語法來攔截它們。
非同步事件
您必須呼叫 Global.asax 中的 AddAsynchronousEventName 方法,來明確地連接 HttpApplication 中非同步事件的事件處理常式。例如,OnPostRequestHandlerExecuteAsync
事件的非同步事件處理常式將呼叫方法 AddOnPostRequestHandlerExecuteAsync(System.Web.BeginEventHandler
, System.Web.EndEventHandler)
來註冊事件。捷徑 Application**_OnEvent**Name 語法僅適用於同步事件。HttpApplication 非同步事件的宣告將如下所示。
void OnAcquireRequestStateAsync(System.Web.BeginEventHandler, System.Web.EndEventHandler)
void OnAuthenticateRequestAsync(System.Web.BeginEventHandler, System.Web.EndEventHandler)
void OnAuthorizeRequestAsync(System.Web.BeginEventHandler, System.Web.EndEventHandler)
void OnBeginRequestAsync(System.Web.BeginEventHandler, System.Web.EndEventHandler)
void OnEndRequestAsync(System.Web.BeginEventHandler, System.Web.EndEventHandler)
void OnPostRequestHandlerExecuteAsync(System.Web.BeginEventHandler, System.Web.EndEventHandler)
void OnPreRequestHandlerExecuteAsync(System.Web.BeginEventHandler, System.Web.EndEventHandler)
void OnReleaseRequestStateAsync(System.Web.BeginEventHandler, System.Web.EndEventHandler)
void OnResolveRequestCacheAsync(System.Web.BeginEventHandler, System.Web.EndEventHandler)
void OnUpdateREquestCacheAsync(System.Web.BeginEventHandler, System.Web.EndEventHandler)
您可以將下列程式碼區塊包含在 Global.asax 中,以便建立 OnPostRequestHandlerExecuteAsync
事件的非同步處理常式。
<%@ language=c# %>
<%@ import namespace="System.Threading" %>
<script runat=server>
public override void Init() {
// Connect the asynchronous event PreRequestHandlerExecuteAsync.
AddOnPreRequestHandlerExecuteAsync(
new BeginEventHandler(this.BeginPreHandlerExecute),
new EndEventHandler(this.EndPreHandlerExecute));
}
IAsyncResult BeginPreHandlerExecute(Object source, EventArgs e, AsyncCallback cb, Object extraData) {
AsynchOperation asynch = new AsynchOperation(cb, Context, extraData);
asynch.StartAsyncWork();
return asynch;
}
void EndPreHandlerExecute(IAsyncResult ar) {
}
class AsynchOperation : IAsyncResult {
private bool _completed;
private Object _state;
private AsyncCallback _callback;
private HttpContext _context;
bool IAsyncResult.IsCompleted { get { return _completed; } }
WaitHandle IAsyncResult.AsyncWaitHandle { get { return null; } }
Object IAsyncResult.AsyncState { get { return _state; } }
bool IAsyncResult.CompletedSynchronously { get { return false; } }
public AsynchOperation(AsyncCallback callback, HttpContext context, Object state) {
_callback = callback;
_context = context;
_state = state;
_completed = false;
}
public void StartAsyncWork() {
ThreadPool.QueueUserWorkItem(new WaitCallback(DoSomething), null /*workItemState*/);
}
private void DoSomething(Object workItemState) {
_context.Items["PreHandlerExecute"] = "Hello World from Async PreHandleExecute!";
_completed = true;
_callback(this);
}
}
</script>