任何由 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 | 发出信号表示有未处理的异常。 |
模块事件
可以连接到(挂钩)由在配置中定义的 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>
在这些类的任何一个中,查找它们定义的公共事件。可以在 Global.asax 中使用语法 ModuleName_OnEventName 挂钩它们。例如,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_OnEventName 语法在自定义模块中挂钩事件。
异步事件
HttpApplication 中异步事件的事件处理程序必须通过调用 Global.asax 中的 AddAsynchronousEventName 方法显式连接。例如,OnPostRequestHandlerExecuteAsync 事件的异步事件处理程序将通过调用 AddOnPostRequestHandlerExecuteAsync(System.Web.BeginEventHandler, System.Web.EndEventHandler) 方法为该事件进行注册。Application_OnEventName 语法的快捷方式仅用于同步事件。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>