
2.3.8 特殊的HttpApplication事件处理
通过global.asax文件,可以简单地完成一些特殊的事件处理,只要按照特定的命名形式,就可以使定义的方法自动注册到对应的事件中。在ASP.NET中,有些事件甚至只能通过global.asax来完成处理。
1.Start事件
这个事件并不是HttpApplication处理管道中的事件,当网站启动后,第一次请求到达网站之后,ASP.NET网站将首先触发一次这个事件,而且在网站的整个生命周期中,也仅仅会触发一次。
触发这个事件的事件源对象是System.Web.HttpApplicationFactory对象,而不是通常的HttpApplication,所以,也不能通过HTTPApplication对象来获取相关的请求参数。在这个事件触发的时候,第一次请求的上下文对象HttpContext也已经创建,所以,可以通过HTTPContext.Current获取第一次的上下文请求对象,然后,通过这个上下文对象来获取相关的信息。
由于这个事件在网站第一次请求的时候触发,所以非常适合针对网站全局的数据进行初始化工作,在ASP.NET MVC中,RouteTable就是在这个事件中创建的。
2.End事件
当网站应用程序被关闭的时候,将触发这个事件。
3.Error事件
当网站应用程序出现错误,或者处理过程中出现未捕获的异常时,HttpApplication将抛出这个事件。
这个事件的事件源是HttpApplication,当前的异常信息可以通过HTTPApplication的Server属性获取HTTPServerUtility的对象实例来完成。HttpServerUtility对象的GetLastError()方法将返回最后一次的异常,这个方法的定义如下:
public Exception GetLastError()
这个异常是一个经过包装的异常,它的InnerException属性指向网站最后一次抛出的未处理异常。
常见的处理如下:
void Application_Error(object sender, EventArgs e) { HttpServerUtility server = (sender as HttpApplication).Server; Exception exception = server.GetLastError().InnerException; // 针对异常的处理 // 清理这个异常 server.ClearError(); }
4.Session的Start事件
当ASP.NET每次创建了一个新的Session后,换句话说,创建了一个新的Session ID之后,就会触发Session的Start事件。需要注意到,在ASP.NET中,支持会话的HttpModule在配置文件中注册的name就是Session。
5.Session的End事件
当一个Session过期之后,或者通过调用Abandon方法被丢弃之后,将会触发Session的End事件。这个事件的事件源实际上是SessionStateModule,而不是HttpApplication。需要注意的是,关闭浏览器并不会导致Session的End事件。而且,如果Session的管理模式是StateServer或者SQLServer的话,将不会触发这个事件。
6.HttpModule的事件注册
从Session的处理可以看出,对于注册到网站中的HttpModule,如果这些Module也会抛出事件,而我们希望能够处理这些HttpModule事件的时候,可以在global.asax中通过定义命名形式如HttpModule注册名称_事件名称的方法来处理HTTPModule的事件。当然,方法必须首先要符合事件的委托定义。
例如,在ASP.NET 2.0之后,提供了匿名用户的标识支持,这是通过一个注册名为AnonymousIdentification的HttpModule实现的,它同时提供了一个名为Creating的事件。定义事件的委托如下:
public delegate void AnonymousIdentificationEventHandler( Object sender, AnonymousIdentificationEventArgs e )
那么,在global.asax中,可以定义如下命名形式的方法来处理这个事件。
public void AnonymousIdentification_Creating( object sender, AnonymousIdentificationEventArgs args ) { }
类似的情况还有个性化数据Profile的事件处理。个性化数据是通过注册名为Profile的HttpModule进行处理的,它的实际类型为ProfileModule,这个类提供了一个名为MigrateAnonymous的合并匿名用户数据的事件,这个事件的委托定义如下:
public delegate void ProfileMigrateEventHandler( Object sender, ProfileMigrateEventArgs e )
所以,可以在global.asax中定义如下形式的方法进行处理。
public void Profile_OnMigrateAnonymous( object sender, ProfileMigrateEventArgs args) { ProfileCommon anonymousProfile = Profile.GetProfile(args.AnonymousID); ProfileManager.DeleteProfile(args.AnonymousID); AnonymousIdentificationModule.ClearAnonymousIdentifier(); //Delete the user row that was created for the anonymous user. Membership.DeleteUser(args.AnonymousID, true); }