1. Application_Start,Application_End,Session_Start,Session_End这四个事件就不用多说了,想必大家都有所了解.
2. Application_Error:
当在web应用程序中有未经处理的错误,这个事件就会引发.该事件有着强大的功能,可以捕获整个应用程序中的所有未处理的 异常,这时你可以把这些异常信息存储在一个log文件中,以便跟踪管理,很方便.
3. Application_OnBeginRequest:
asp.net应用程序的每个请求都会引发该事件,它发生在页面,web服务和其他任何http处理程序请求之前.它也不同于application_Start事件,后者只在启动应用程序时引发一次.
4. Application_OnAuthenticateRequest: 该事件发生在asp.net准备对请求执行认证时.该事件很容易为asp.net建立自定义的身份验证系统.
5. Application_OnAuthorizeRequest: 该事件发生在asp.net准备授权一个请求资源的访问权限时.
6. Application_OnResolveRequestCache: asp.net 有一个强大的页面和web服务输出高速缓存的功能,页面可以在执行一次后静态的保存起来,以供以后的请求使用.该事件就是在asp.net准备确定是否从 cache中处理请求时触发的.
7. Application_OnAcquireRequestState: 这个事件是在asp.net准备从进程中及进程外window service 或sql server中获得session状态数据时引发的.
8. application_OnPreRequestHandleExecute: 这个事件是在请求的处理程序调用之前引发的.
9. Application_OnPostRequestHandleExecute: 这个事件是在处理程序完成了对请求的处理之后引发的.这之后Response对象把数据送回客户端.
10. Applicaiton_OnReleaseRequestState: 用来释放session数据并在必要时更新存储器的.
11. Applicaiton_OnUpdateRequestCache: 这个事件是在asp.net用当前请求更新告诉缓存时发生的.
12. Application_OnEndRequest: 这是请求完成所引发的最后一个事件.
13. Application_OnPreSendRequestsHeaders: 在http标题发送到请求的客户端之前发生的.
14.Application_OnPreSendRequestContent: 是在Http主体发送到请求的客户端之前发生的.
15. Applicaton_OnDisposed: 这一事件是在asp.net应用程序最终关闭,而且clr从内存中删除了asp.net应用程序时引发的.
以上这些事件其实并不一定都会用到,但很多事件还是很有用的.
举个例子,像Application_OnBeginRequest事件,它触发在每个用户请求发送时,利用这一事件我们可以轻松的加入一个计数器,用来计算服务器在一段时间内,回应了多少个用户请求.
而application_OnEndRequest 事件则发生在所有请求完毕所有,即将将数据输出给用户,我们可以利用这一事件来加入一些对每个页面都需要加入的东东.比如: this site is powered by asp.net等等之类的信息,这样,无论用户请求该站点下的哪个页面,都将在页面底部显示出this site is powered by asp.net的字样.
另外一个很重要的事件就是application_error事件. 在我们的应用程序中,有时候不可能估计到全部的异常,这样,一旦这样的异常发生,将导致显示黄页,很不友好,而在application_error事件中定义异常则很方便.
<script language="C#" runat=server>
protected void Application_Error(Object sender, EventArgs e)
{
string LogName="Web_Error";
string message="";
message="URL:"+Request.Path+";Error:"+Server.GetLastError().ToString();
//检查日志是否存在
if(!EventLog.SourceExists(LogName))
{
EventLog.CreateEventSource(LogName,LogName);
}
EventLog log= new EventLog();
log.Source=LogName;
log.WriteEntry(message,EventLogEntryType.Error);
}
</script>
------------------------------------------------------------------------
Global.asax 文件,有时候叫做 ASP.NET 应用程序文件,提供了一种在一个中心位置响应应用程序级或模块级事件的方法。你可以使用这个文件实现应用程序安全性以及其它一些任务。下面让我们详细看一下如何在应用程序开发工作中使用这个文件。
概述
Global.asax 位于应用程序根目录下。虽然 Visual Studio .NET 会自动插入这个文件到所有的 ASP.NET 项目中,但是它实际上是一个可选文件。删除它不会出问题——当然是在你没有使用它的情况下。.asax 文件扩展名指出它是一个应用程序文件,而不是一个使用 aspx 的 ASP.NET 文件。
Global.asax 文件被配置为任何(通过 URL 的)直接 HTTP 请求都被自动拒绝,所以用户不能下载或查看其内容。ASP.NET 页面框架能够自动识别出对Global.asax 文件所做的任何更改。在 Global.asax 被更改后ASP.NET 页面框架会重新启动应用程序,包括关闭所有的浏览器会话,去除所有状态信息,并重新启动应用程序域。
编程
Global.asax 文件继承自HttpApplication 类,它维护一个HttpApplication 对象池,并在需要时将对象池中的对象分配给应用程序。Global.asax 文件包含以下事件:
· Application_Init:在应用程序被实例化或第一次被调用时,该事件被触发。对于所有的HttpApplication 对象实例,它都会被调用。
· Application_Disposed:在应用程序被销毁之前触发。这是清除以前所用资源的理想位置。
· Application_Error:当应用程序中遇到一个未处理的异常时,该事件被触发。
· Application_Start:在HttpApplication 类的第一个实例被创建时,该事件被触发。它允许你创建可以由所有HttpApplication 实例访问的对象。
· Application_End:在HttpApplication 类的最后一个实例被销毁时,该事件被触发。在一个应用程序的生命周期内它只被触发一次。
· Application_BeginRequest:在接收到一个应用程序请求时触发。对于一个请求来说,它是第一个被触发的事件,请求一般是用户输入的一个页面请求(URL)。
· Application_EndRequest:针对应用程序请求的最后一个事件。
· Application_PreRequestHandlerExecute:在 ASP.NET 页面框架开始执行诸如页面或 Web 服务之类的事件处理程序之前,该事件被触发。
· Application_PostRequestHandlerExecute:在 ASP.NET 页面框架结束执行一个事件处理程序时,该事件被触发。
· Applcation_PreSendRequestHeaders:在 ASP.NET 页面框架发送 HTTP 头给请求客户(浏览器)时,该事件被触发。
· Application_PreSendContent:在 ASP.NET 页面框架发送内容给请求客户(浏览器)时,该事件被触发。
· Application_AcquireRequestState:在 ASP.NET 页面框架得到与当前请求相关的当前状态(Session 状态)时,该事件被触发。
· Application_ReleaseRequestState:在 ASP.NET 页面框架执行完所有的事件处理程序时,该事件被触发。这将导致所有的状态模块保存它们当前的状态数据。
· Application_ResolveRequestCache:在 ASP.NET 页面框架完成一个授权请求时,该事件被触发。它允许缓存模块从缓存中为请求提供服务,从而绕过事件处理程序的执行。
· Application_UpdateRequestCache:在 ASP.NET 页面框架完成事件处理程序的执行时,该事件被触发,从而使缓存模块存储响应数据,以供响应后续的请求时使用。
· Application_AuthenticateRequest:在安全模块建立起当前用户的有效的身份时,该事件被触发。在这个时候,用户的凭据将会被验证。
· Application_AuthorizeRequest:当安全模块确认一个用户可以访问资源之后,该事件被触发。
· Session_Start:在一个新用户访问应用程序 Web 站点时,该事件被触发。
· Session_End:在一个用户的会话超时、结束或他们离开应用程序 Web 站点时,该事件被触发。
这个事件列表看起来好像多得吓人,但是在不同环境下这些事件可能会非常有用。
使用这些事件的一个关键问题是知道它们被触发的顺序。Application_Init 和Application_Start 事件在应用程序第一次启动时被触发一次。相似地,Application_Disposed 和 Application_End 事件在应用程序终止时被触发一次。此外,基于会话的事件(Session_Start 和 Session_End)只在用户进入和离开站点时被使用。其余的事件则处理应用程序请求,这些事件被触发的顺序是:
· Application_BeginRequest
· Application_AuthenticateRequest
· Application_AuthorizeRequest
· Application_ResolveRequestCache
· Application_AcquireRequestState
· Application_PreRequestHandlerExecute
· Application_PreSendRequestHeaders
· Application_PreSendRequestContent
· <<执行代码>>
· Application_PostRequestHandlerExecute
· Application_ReleaseRequestState
· Application_UpdateRequestCache
· Application_EndRequest
这些事件常被用于安全性方面。下面这个 C# 的例子演示了不同的Global.asax 事件,该例使用Application_Authenticate 事件来完成通过 cookie 的基于表单(form)的身份验证。此外,Application_Start 事件填充一个应用程序变量,而Session_Start 填充一个会话变量。Application_Error 事件显示一个简单的消息用以说明发生的错误。
protected void Application_Start(Object sender, EventArgs e) {
Application["Title"] = "Builder.com Sample";
}
protected void Session_Start(Object sender, EventArgs e) {
Session["startValue"] = 0;
}
protected void Application_AuthenticateRequest(Object sender, EventArgs e) {
// Extract the forms authentication cookie
string cookieName = FormsAuthentication.FormsCookieName;
HttpCookie authCookie = Context.Request.Cookies[cookieName];
if(null == authCookie) {
// There is no authentication cookie.
return;
}
FormsAuthenticationTicket authTicket = null;
try {
authTicket = FormsAuthentication.Decrypt(authCookie.Value);
} catch(Exception ex) {
// Log exception details (omitted for simplicity)
return;
}
if (null == authTicket) {
// Cookie failed to decrypt.
return;
}
// When the ticket was created, the UserData property was assigned
// a pipe delimited string of role names.
string[2] roles
roles[0] = "One"
roles[1] = "Two"
// Create an Identity object
FormsIdentity id = new FormsIdentity( authTicket );
// This principal will flow throughout the request.
GenericPrincipal principal = new GenericPrincipal(id, roles);
// Attach the new principal object to the current HttpContext object
Context.User = principal;
}
protected void Application_Error(Object sender, EventArgs e) {
Response.Write("Error encountered.");
}
这个例子只是很简单地使用了一些Global.asax 文件中的事件;重要的是要意识到这些事件是与整个应用程序相关的。这样,所有放在其中的方法都会通过应用程序的代码被提供,这就是它的名字为Global 的原因。
这里是前面的例子相应的 VB.NET 代码:
Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
Application("Title") = "Builder.com Sample"
End Sub
Sub Session_Start(ByVal sender As Object, ByVal e As EventArgs)
Session("startValue") = 0
End Sub
Sub Application_AuthenticateRequest(ByVal sender As Object, ByVal e As
EventArgs)
' Extract the forms authentication cookie
Dim cookieName As String
cookieName = FormsAuthentication.FormsCookieName
Dim authCookie As HttpCookie
authCookie = Context.Request.Cookies(cookieName)
If (authCookie Is Nothing) Then
' There is no authentication cookie.
Return
End If
Dim authTicket As FormsAuthenticationTicket
authTicket = Nothing
Try
authTicket = FormsAuthentication.Decrypt(authCookie.Value)
Catch ex As Exception
' Log exception details (omitted for simplicity)
Return
End Try
Dim roles(2) As String
roles(0) = "One"
roles(1) = "Two"
Dim id As FormsIdentity
id = New FormsIdentity(authTicket)
Dim principal As GenericPrincipal
principal = New GenericPrincipal(id, roles)
' Attach the new principal object to the current HttpContext object
Context.User = principal
End Sub
Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs)
Response.Write("Error encountered.")
End Sub
资源
Global.asax 文件是 ASP.NET 应用程序的中心点。它提供无数的事件来处理不同的应用程序级任务,比如用户身份验证、应用程序启动以及处理用户会话等。你应该熟悉这个可选文件,这样就可以构建出健壮的ASP.NET 应用程序。
------------------------------------------------------------------------------------
【转自】Global.asax详解
global.asax是一个文本文件,它提供全局可用代码。这些代码包括应用程序的事件处理程序以及会话事件、方法和静态变量。有时该文件也被称为应用程序文件。
global.asax文件中的任何代码都是它所在的应用程序的一部分。每个应用程序在其根 目录下只能有一个global.asax文件。然而,这个文件是可选的。如果没有global.asax文件,应用程序将对所有事件应用由 HttpApplication类提供的默认行为。
提示:经典ASP有一个与global.asax类似格式和构造的,名为global.asa的文件。实际上,如果将一个正在运行的global.asa文件代码复制到global.asax中,应用程序同样可以运行。
当应用程序运行的时候,global.asax的内容被编译到一个继承自HttpApplication类的类中。因此,HttpApplication类中所有的方法、类和对象对于应用程序都是可用的。
CLR监控着global.asax的变化。如果它察觉到这个文件发生了改变,那么将自动启 动一个新的应用程序复本,同时创建一个新的应用程序域。原应用程序域当前正在处理的请求被允许结束,而任何新的请求都交由新应用程序域来处理。当原应用程 序域的最后一个请求处理完成时,这个应用程序域即被清除。这有效的保证了应用程序可以重新启动,而不被任何用户察觉。
为防止应用程序用户下载应用程序而看到源代码,ASP.NET缺省配置为阻止用户查看global.asax的内容。如果有人在浏览器输入以下URL:
http://localhost/progaspnet/Global.asax
这将会收到一个403(禁止访问)错误信息或者类似的信息如:
This type of page is not served。
提示:简单而言,web.config文件与global.asax有些类似的地方。如果这个文件被更改,应用程序将自动“重启”。同样,也不可能在浏览器中查看web.config文件。
Global.asax文件从外观和结构上与页面文件(.aspx)相似。它可以有一个或多个部分,简要描述如下:
l 指令
l 脚本块
l Object声明
正如Web页和Web服务能够使用代码隐藏功能,global.asax同样也可以。然而,与Web页和Web服务的条件有所不同,VS2005默认状态下不对global.asax使用代码隐藏功能。
提示:Visual Studio 2005预览版默认对global.asax使用代码隐藏模型。目前仍然支持代码隐藏,但不是默认使用。
为了对global.asax使用代码隐藏技术,可使用位于该文件头部的Application指令(类似于页面文件的Page指令,下一节将详细介绍)的Inherits属性,该属性指向global.asax.cs中的代码隐藏类。
同时,也有一个CodeBehind属性用来指向代码隐藏文件。然而,如果它指向的是一个位于App_Code文件夹以外的位置,那么必须对这个类文件进行手动编辑。
通过右键单击解决方案资源管理器中的网站或者单击网站菜单,然后选择“Add New Item...”,接着选择全局应用程序类,可以为Web应用程序添加一个global.asax文件。保留默认名称global.asax。
VS2005将创建一个如示例18-1所列的文件。模板中包括对以下5个事件的空白声明:Application_Start、Application_End、Session_Start、Session_End和Applica- tion_Error。
示例18-1:global.asax模板
<%@ Application Language="C#" %>
在示例18-2所列举的global.asax文件中,为应用程序状态设置了一些值,同时,在每次应用程序启动的时候向日志文件写一个条目。为了使用这个示例,需要保证ASP.NET帐户对根目录c:"具有写入权限(在产品系统中不推荐)。
示例18-2:global.asax示例
<%@ Application Language="C#"%>
指令
与Web页和Web服务文件相比,global.asax可以以多个指令作为开始。这些指令在处理ASP.NET文件时指定应用程序编译的设置。与Page指令相比,Application指令可
接受一个或者多个具有字典结构的属性/值对。此处支持三个指令:Application、Import和Assembly。
Application Application指令设置编译器的应用程序专用属性。以下是一个Application指令示例:
<%@ Application Language="C#" Inherits="WebServiceConsumer.Global"
Description="A sample application" %>
Language属性可以设置为任何一种标准语言名称:VB、C#、JS、或VJ#,它们分 别对应VB2005、C#、JScript.NET或J#。(可以使用任何一种支持.NET平台的第三方语言)默认值为C#。此处的Language设置 的是语言专门用于global.asax文件,而非其他应用程序代码文件。例如,可以完全合法地在global.asax文件中使用C#,在.aspx文 件中使用VB2005,相反亦然。
Inherits属性指定所继承类名,具有代表性的如代码隐藏文件中的类。
Description属性接受对应用程序的文本描述,而分析器和编译器将会忽略它。
CodeBehind属性在Visual Studio .NET(非VS2005)中用来指定包含的代码隐藏文件。
Import Import指令仅包括一个Namespace属性。所指定名字空间被明确地导入应用程序中,使其所有的类和接口都可用。导入的名字空间可以是.NET Framework的一部分或者用户自定义的名字空间。
以下是一个典型的Import指令:
<%@ Import Namespace="System.Data" %>
只能有一个Namespace属性。如果需要导入多个名字空间,那么需要使用多个Import指令。
下列名字空间自动导入到所有的Web应用程序中,所以没必要使用Import指令。
l System
l System.Collections
l System.Collections.Specialized
l System.Configuration
l System.IO
l System.Text
l System.Text.RegularExpressions
l System.Web
l System.Web.Caching
l System.Web.Security
l System.Web.SessionState
l System.Web.UI
l System.Web.UI.HtmlControls
l System.Web.UI.WebControls
Assembly Assembly指令用于在编译过程中将一个程序集链接到当前应用程序。这样可以使所有程序集的类与接口对应用程序都是可用的。
提示:典型的程序集是.dll或.exe文件,这将在下一章中详细讲解。
由于在编译时引用程序集,所以可以使用Assembly指令绑定程序集,然后在运行时将其加载到应用程序池中。
位于应用程序集缓存(也就是位于bin目录和App_Code目录中的代码文件)中的程序集可自动连接到应用程序。因此,任何位于bin目录的程序集,或者由App_Code目录中的代码编译而来的任何程序集,都不需要使用Assembly指令实现连接。
Assembly指令包括两个属性:Name和Src。Name属性是一个字符串,表示连接到应用程序的程序集名字,它不能包含路径。Src属性则是指向源文件的路径(只能为相对路径),这些文件将被动态编译和连接。
每个程序集指令只能有一个属性。如果需要连接多个程序集,则应使用多个Assembly指令。
Assembly指令类似于:
<%@ Assembly %>
<%@ Assembly Src="sources/SomeSourceFile.cs" %>
脚本块
典型的global.asax文件中包含大量代码,这些代码包含在以script标签起止的脚本块中:
如果使用代码隐藏,虽然代码隐藏文件中的代码本身没有附加script标签,但包含在代码隐藏文件中的代码与脚本块中的代码是等效的。
脚本块中的代码可以包含事件处理程序或者方法,下文将对此进行讲解。
事件
如同Web页和控件可以公开事件一样,应用程序中的Application对象和 Session对象也能够公开事件。这些事件能被global.asax文件或指定的文件中的事件处理程序处理。例如,当应用程序开始执行时,触发 Application_Start事件;当应用程序结束时,触发Application_End事件。Application的某些事件是每当页面请求 时触发,而其他一些事件,例如Application_Error,则仅在特定情况下触发。
示例18-2中的global.asax文件代码说明了Application_Start 和Application_End事件。示例18-2中的Application_Start事件设置了两个Application属性:一个是名为 strConnectionString的字符串,一个是名为arBooks的字符串数组。事件处理程序方法调用一个名为WriteFile的辅助方法, 它包含在global.asax文件中。该辅助方法将一个字符串写入日志文件中。以下是示例18-2中的WriteFile方法代码:
void WriteFile(string strText)
{
System.IO.StreamWriter writer =
new System.IO.StreamWriter(@"C:"test.txt",true);
string str;
str = DateTime.Now.ToString( ) + " " + strText;
writer.WriteLine(str);
writer.Close( );
}
WriteFile是一个简单的记录日志的方法。该方法初始化一个基于文本文件的 StreamWriter对象,并对c:"test.txt进行硬编码。它在文件中添加了一个时间戳,并写入通过方法传递的字符串。 StreamWriter方法的布尔值参数为true,其表示如果文件已经存在,那么将文本行追加到文件中。如果文件不存在,则创建一个文件。
Application_End事件处理方法调用了另一个WriteFile方法,它添加了一个日志条目以记录应用程序结束。
为了查看这两个事件处理程序的结果,可对global.asax进行一些无意义的编辑,并保 存文件。此时将强制结束应用程序。然后请求虚拟目录中的任意URL地址。例如,使用上一章中的一个网页——实际上无论哪一个——或者一个自己创建的网页。 示例18-3显示了日志文件内容。
示例18-3:Test.txt摘录
8/26/2006 5:46:23 PM Application Starting
8/26/2006 6:13:35 PM Application Ending
8/27/2006 10:17:39 PM Application Starting
8/27/2006 10:18:23 PM Application Ending
8/27/2006 10:18:36 PM Application Starting
如同Application对象的Start和End事件一样,Session对象也拥有Session_ Start和Session_End事件。这将允许应用程序每次启动和结束过程中为每个会话都运行代码。
如示例18-4中高亮显示的方法名所示,其包括了global.asax文件中所有可能的应用程序事件处理程序。在页面请求被接受、处理和呈现过程中,可以容易地查看应用程序生命周期。
示例18-4:Global.asax事件说明
<%@ Application Language="C#" %>
以下是页面请求触发的所有事件,以触发顺序排序:
Application_BeginRequest
当ASP.NET开始处理每个请求时触发。在这个事件处理中的代码将在页面或者服务处理请求之前执行。
Application_AuthenticateRequest
在验证请求之前触发。(正如第12章介绍的,验证是确认用户就是他所说的那个人的过程)在这个事件处理程序的代码中允许实现自定义安全管道。
Application_AuthorizeRequest
在为请求授权之前触发。(授权是确定是否请求用户具有访问资源的权限的过程,在
第12章已经介绍过)在这个事件处理程序的代码中允许实现自定义安全管道。
Application_ResolveRequestCache
在ASP.NET确定是否应该生成新的输出,或者由缓存填充前触发。无论何种情况,都将执行该事件处理程序中的代码。
Application_AcquireRequestState
在获取会话状态之前执行。
Application_PreRequestHandlerExecute
在将请求发送到服务于请求的处理程序对象之前触发。当事件触发后,页面将由HTTP处理程序处理请求。
Application_PostRequestHandlerExecute
当HTTP处理程序与页面请求一起完成时触发。此时,Response对象将获得由客户端返回的数据。
Application_ReleaseRequestState
当释放和更新试图状态时触发。
Application_UpdateRequestCache
如果输出被缓存,那么缓存更新时将触发。
Application_EndRequest
当请求结束时执行。
Application_PreSendRequestHeaders
在向客户端发送HTTP头之前触发。如果启用响应缓存,这意味着直到所有数据都准备好(默认 条件),都不会发送任何数据。该事件总是在Application_EndRequest事件之后。如果禁用响应缓存,那么无论何时将数据发送给客户端, 都将触发该事件。响应控制由Page指令的一个属性,或者Web服务的WebMethod属性控制。
Application_PreSendRequestContent
向客户端发送HTTP内容之前触发。和Application_PreSendRequestHeaders事件一样,Application_PreSendRequestContent事件能否被触发取决于响应缓存是否可用。
以下列举应用程序事件,它们在特定条件下触发:
Application_Start
当应用程序启动时触发。当首次请求应用程序虚拟目录中的任何页面时,将启动应用程序,同时如果应用程序已经运行,则不触发该事件。
Application_End
应用程序结束时触发。无论何时修改了配置文件(global.asax、global.asax.cs、
global.asax.vb或者web.config),或者服务器崩溃或者重启,应用程序都将结束。通常在该事件处理程序中执行清除功能的代码,例如关闭数据库连接。
Session_Start
每个会话开始时触发,这是放置具体会话代码的地方。
Session_End
会话结束时触发。它为保存存储在会话中的任何数据提供了机会。
Application_Disposed
当CLR从内存中移除应用程序时触发。
Application_Error
无论在应用程序中何时何处发生未处理的错误都将触发。它提供了一个实现通用应用程序错误处理的好机会。
使用try...catch语句块能够在代码中处理特定错误,也可以使用Page指令的ErrorPage属性来捕获页面级错误。使用这些方式处理任何错误都不会触发Application_Error事件。
为了测试新版的global.asax,在示例18-5中创建一个网页。查看GlobalEvents站点。当该网页运行时,将看到如图18-4所示的页面。
示例18-5:GlobalEvents网站的default.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs"
Inherits="_Default" %>
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
Global Events
Text="End Session"
OnClick="btnEndSession_Click" />
Text="Generate Error"
OnClick="btnError_Click" />
图18-4:GlobalEvents
如图18-4所示,可看到触发了一系列应用程序事件。在这些事件执行的中途,呈现了.aspx页面自身,接着是另一些应用程序事件。
警告:示例GlobalEvents必须在一个真实的IIS虚拟路径下才能良好运行。
页面第一次显示时触发Session_Start事件,而在随后的显示中则不再触发该事件。 这是因为请求是相同的会话。单击“End Session”按钮,调用Session.Abandon方法,这将结束当前会话。下一次页面被提交到服务器时,将再次触发Session_Start 事件。
Post按钮提供了一个简单的再次提交页面的方法。
示例18-4中大部分的应用程序事件处理程序都使用了Response.Write方法,以 便显示触发的事件。然而,Application_Start和Application_End方法调用了WriteFile方法。如果在这些事件处理程 序中试图使用Response.Write方法,那么在页面中将不会
显示。因为那时用于呈现的页面会话还没有运行。但是,当检查日志文件c:"test.txt时,将看到应用程序启动和结束所显示的条目。
示例18-4所示的global.asax文件说明了一种使用Application_Error事件的方法。以下列举了这些代码:
protected void Application_Error(Object sender, EventArgs e)
{
string strError;
strError = Server.GetLastError( ).ToString( );
if (Context!= null)
Context.ClearError( );
Response.Write("Application_Error" + "
");
Response.Write("Error Msg: " + strError + "
" +
"End Error Msg
");
}
该事件处理程序使用HttpServerUtility对象的GetLastError方法,以报告最后出现的错误。这个错误被转换为一个字符串,并被指定给一个字符串变量:
strError = Server.GetLastError( ).ToString( )
接下来调用HttpContext对象的ClearError方法来清除目前HTTP请求中的所有错误:
Context.ClearError( )
如果没有将错误清除,那么错误将显示在客户端浏览器,并且还是无法看见Respons- e.Write方法的显示结果。
最后,Response.Write方法显示一个信息,当前的错误将显示在客户端。
另一种向用户报告错误的方式是显示自定义错误处理页面。为此,需要使用以下代码行替代Application_Error事件处理程序中的Response.Write方法:
Response.Redirect("CustomErrorPage.aspx?Msg=" +
Server.UrlEncode(strError));
以上代码行调用HttpServerUtility对象的UrlEncode方法,其将错误 信息作为一个QueryString参数传递给CustomErrorPage.aspx页面中的自定义错误处理代码。 CustomErrorPage.aspx页面有一个名为lblMessage的Label控件。以下是页面中的Page_Load方法代码:
void Page_Load(Object Source, EventArgs E)
{
lblMessage.Text = Request.QueryString["Msg"];
}
Default.aspx中的Generate Error按钮故意触发一个错误,以便查看错误处理。该按钮的单击事件处理程序的代码如下所示,它将除零异常:
protected void btnError_Click(object sender, EventArgs e)
{
int a = 5;
int b = 0;
int c;
c = a / b;
}
服务器端包括
使用服务器端包括能够实现在应用程序中包含外部源代码文件。在编译之前,包括文件中的代码将被添加到global.asax文件中。尽管应用程序的语言可能与包括文件的语言不同,但是用于包括文件的语言必须与global.asax文件所使用的语言匹配。
下面是用于服务器端的语法:
在这个句法中,PathType类型可以是表18-1所示之一。
表18-1 PathType属性
路径类型 |
说 明 |
File |
文件名是包含global.asax文件的目录的相对路径 |
Virtual |
文件名是包含网站虚拟目录的虚拟路径 |
查看示例18-4所示的global.asax文件,将下面的代码添加到第二行中:
创建一个新的名为IncludeFile.cs的文本文件,将该文件和global.asax存储在同一目录下。这个文件需要与global.asax文件一样的一对脚本标签。
将global.asax页面中的WriteFile方法复制到包括文件中,然后注释(或者删除)global.asax页面中的WriteFile方法。这样包括文件应类似于示例18-6。
示例18-6:具有包括文件的global.asax
如果运行任意一个网页,那么将不会与先前有什么区别,因为您所做的只是把一个文件中的代码转移到另外一个文件中。
如果CLR监视global.asax文件的变化,并和重新启动应用程序一样,CLR也监视包括文件的变化。如果包括文件发生变化,那么应用程序也会重新启动。
对于在多个应用程序中所包括的相同标准代码而言,包括文件非常有用。这些通用代码可能包括数据库访问方法、写入日志记录、错误处理管道、登录或者每个应用程序的基础类型代码片段。
对象声明
在global.asax文件中包括代码的另一个方法是是声明object标签。这些声明的静态对象要么是Application,或者是Session对象。这样就可以在应用程序或者每个会话过程中使用。
---------------------------------------------------------------------------
一点自己的总结:
Session,在Application_AcquireRequestState和Application_PostRequestHandler两个事件之间才能使用,其它事件中,除Session_Start和Session_End外,都不能使用。
当Application_Error被触发后,会直接执行 Application_EndRequest,从而跳过中间的几个事件。
Response.End()方法,会跳过一些事件,直接触发Application_OnEndRequest事件。