任何由 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>