运行时错误:在页执行期间发生,即使编译时检测不到该错误。
默认情况下,为运行时错误显示的信息是调用堆栈(导致异常的过程调用链)。如果启用了调试模式,ASP.NET 将显示源代码中发生运行时错误的行号。调试模式是有价值的应用程序调试工具。可以通过下列指令启用页级别调试模式:
也可以通过应用程序根目录中的 Web.config 文件启用应用程序级别的调试模式,如下面的示例所示。
注意:运行调试模式将产生严重的性能损失。在部署已完成的应用程序之前,请务必禁用该模式。
下面的示例说明如何使用调试模式显示运行时异常的源行号。
自定义错误页
根据具体的情况,可能需要以不同的方式处理应用程序错误。例如,开发时可能需要查看 ASP.NET 提供的详细错误页,以帮助确定和修复问题。然而,一旦应用程序应用于生产环境,您可能不想向客户所在的客户端显示详细的错误。可以使用 ASP.NET 指定是向本地客户端、远程客户端还是这两者显示错误。默认情况下,仅向本地客户端(即服务器所在的同一计算机上的客户端)显示错误。也可以指定自定义错误页,以在发生错误时将客户端重定向到该页。
在 Web.config 文件中为某个应用程序启用自定义错误。例如:
<configuration>
<system.web>
<customErrors defaultRedirect="genericerror.htm" mode="remoteonly" />
</system.web>
</configuration>
此配置使本地客户端能够看到默认的 ASP.NET 详细错误页,但将远程客户端重定向到自定义页 genericerror.htm。该页也可以是 .aspx 页。ASP.NET 以 QueryString 参数的形式将发生错误的页的路径传递到该错误页。注意:如果执行错误页时产生错误,则将给远程客户端发回空白页。
<%@ Page Language="C#" Description="Error page"%>
<html>
<head>
<title>Error page</title>
</head>
<body>
<h1>Error page</h1>
Error originated on: <%=Request.QueryString["ErrorPage"] %>
</body>
</html>
<%@ Page Language="VB" Description="Error page"%>
<html>
<head>
<title>Error page</title>
</head>
<body>
<h1>Error page</h1>
Error originated on: <%=Request.QueryString("ErrorPage") %>
</body>
</html>
<%@ Page Language="JScript" Description="Error page"%>
<html>
<head>
<title>Error page</title>
</head>
<body>
<h1>Error page</h1>
Error originated on: <%=Request.QueryString["ErrorPage"] %>
</body>
</html>
|
| C# |
VB |
JScript |
|
注意:只有映射到 IIS 中的 aspnet_isapi.dll 扩展的文件才产生这些错误。不通过 aspnet_isapi.dll 接受服务的文件不会被 ASP.NET 处理并且产生 IIS 错误。有关配置 IIS 自定义错误的信息,请参阅 IIS 文档。
下表描述了 <customerrors> 标记的配置属性和值。
| 属性 |
说明 |
| Mode |
指示是启用、禁用自定义错误还是只将其显示给远程计算机。值:On、Off、RemoteOnly(默认)。 |
| DefaultRedirect |
指示发生错误时浏览器应重定向到的默认 URL。此属性可选。 |
Mode 属性确定是向本地客户端、远程客户端还是这两者显示错误。下表描述了每项设置的作用。
| Mode |
本地宿主请求 |
远程宿主请求 |
| On |
自定义错误页。 |
自定义错误页。 |
| Off |
ASP.NET 错误页。 |
ASP.NET 错误页。 |
| RemoteOnly |
ASP.NET 错误页。 |
自定义错误页。 |
下面的示例说明如何使用 <customerrors> 配置节。
除了将所有的错误重定向到一个公共页外,还可以将特定的错误页分配给特定的错误状态代码。<customerrors> 配置节支持内部 <error> 标记,该标记使 HTTP 状态代码与自定义错误页关联。例如:
<configuration>
<system.web>
<customErrors mode="RemoteOnly" defaultRedirect="/genericerror.htm">
<error statusCode="500" redirect="/error/callsupport.htm"/>
<error statusCode="404" redirect="/error/notfound.aspx"/>
<error statusCode="403" redirect="/error/noaccess.aspx"/>
</customErrors>
</system.web>
</configuration>
下表描述了 <error> 标记的属性和值。
| 属性 |
说明 |
| StatusCode |
自定义错误页应用于的 HTTP 错误状态代码。例如:403 已禁止、404 未找到、500 内部服务器错误。 |
| Redirect |
发生错误时客户端浏览器应重定向到的 URL。 |
下面的示例说明如何使用 <error> 标记。注意:此示例为“未找到文件”错误指定的是 .aspx 页,以便可以输出通过 QueryString 传递的丢失页 URL。
以编程方式处理错误
也可以在页级别或者应用程序级别处理代码错误。Page 基类公开了一个 Page_Error 方法,此方法在页中可以被重写。每当运行时引发未捕获的异常时都调用此方法。
<script language="C#" runat="server">
void Page_Error(Object source, EventArgs e) {
String message = "<font face=verdana color=red>"
+ "<h4>" + Request.Url.ToString() + "</h4>"
+ "<pre><font color='red'>" + Server.GetLastError().ToString() + "</pre>"
+ "</font>";
Response.Write(message);
}
</script>
<script language="C#" runat="server">
Sub Page_Error(Source As Object, E As EventArgs)
Dim message As String = "<font face=verdana color=red>" _
& "<h4>" & Request.Url.ToString() & "</h4>" _
& "<pre><font color='red'>" & Server.GetLastError().ToString() & "</pre>" _
& "</font>"
Response.Write(message)
End Sub
</script>
<script language="JScript" runat="server">
function Page_Error(source:Object, e:EventArgs) : void {
var message:String = "<font face=verdana color=red>"
+ "<h4>" + Request.Url.ToString() + "</h4>"
+ "<pre><font color='red'>" + Server.GetLastError().ToString() + "</pre>"
+ "</font>";
Response.Write(message);
}
</script>
|
| C# |
VB |
JScript |
|
下面的示例说明 Page_Error 方法。
可以用此方法做一些有用的事情,如向站点管理员发送电子邮件,告知该页未能正确执行。为此,ASP.NET 在 System.Web.Mail 命名空间中提供了一个类集。若要导入此命名空间,请在页顶部使用 @Import 指令,如下所示:
<%@ Import Namespace="System.Web.Mail" %>
然后可以使用 MailMessage 和 SmtpMail 对象以编程方式发送电子邮件。
MailMessage mail = new MailMessage();
mail.From = "automated@yourservername.com";
mail.To = "administrator@yourservername.com";
mail.Subject = "Site Error";
mail.Body = message;
mail.BodyFormat = MailFormat.Html;
SmtpMail.Send(mail);
Dim mail As New MailMessage
mail.From = "automated@yourservername.com"
mail.To = "administrator@yourservername.com"
mail.Subject = "Site Error"
mail.Body = message
mail.BodyFormat = MailFormat.Html
SmtpMail.Send(mail)
var mail:MailMessage = new MailMessage();
mail.From = "automated@yourservername.com";
mail.To = "administrator@yourservername.com";
mail.Subject = "Site Error";
mail.Body = message;
mail.BodyFormat = MailFormat.Html;
SmtpMail.Send(mail);
|
| C# |
VB |
JScript |
|
下面的示例说明如何发送邮件信息以响应页错误。
注意:除非已在计算机上配置了 SMTP 邮件服务,否则该示例不会真正发送邮件。有关 SMTP 邮件服务的更多信息,请参考 IIS 文档。
除了在页级别处理错误外,可能还需要在应用程序级别处理错误。为此,请使用 Global.asax 中的 Application_Error 事件。对于应用程序中引发的任何未处理异常都会引发此事件。
void Application_Error(Object sender, EventArgs e) {
//...Do something here
}
Sub Application_Error(sender As Object, e As EventArgs)
'...Do something here
End Sub
function Application_Error(sender:Object, e:EventArgs) : void {
//...Do something here
}
|
| C# |
VB |
JScript |
|
写入事件日志
System.Diagnostics 命名空间提供了写入 Windows 事件日志的类。若要在页中使用此命名空间,必须先导入此命名空间,如下所示:
<%@ Import Namespace="System.Diagnostics"%>
EventLog 类封装日志本身。它提供了检测或创建日志的静态方法,并且可被实例化以从代码写入日志项。下面的示例说明了 Global.asax 的 Application_Error 方法中的此功能。每当应用程序中发生未处理的异常时,包含错误信息和堆栈跟踪的项便写入应用程序日志。
void Application_Error(Object sender, EventArgs e) {
String Message = "\n\nURL:\n http://localhost/" + Request.Path
+ "\n\nMESSAGE:\n " + Server.GetLastError().Message
+ "\n\nSTACK TRACE:\n" + Server.GetLastError().StackTrace;
// Create event Log if it does not exist
String LogName = "Application";
if (!EventLog.SourceExists(LogName)) {
EventLog.CreateEventSource(LogName, LogName);
}
// Insert into event log
EventLog Log = new EventLog();
Log.Source = LogName;
Log.WriteEntry(Message, EventLogEntryType.Error);
}
Sub Application_Error(sender As Object, e As EventArgs)
Dim Message As String = "\n\nURL:\n http://localhost/" & Request.Path _
& "\n\nMESSAGE:\n " & Server.GetLastError().Message _
& "\n\nSTACK TRACE:\n" & Server.GetLastError().StackTrace
' Create event log if it does not exist
Dim LogName As String = "Application"
If (Not EventLog.SourceExists(LogName))
EventLog.CreateEventSource(LogName, LogName)
End If
' Insert into event log
Dim Log As New EventLog
Log.Source = LogName
Log.WriteEntry(Message, EventLogEntryType.Error)
End Sub
function Application_Error(sender:Object, e:EventArgs) : void {
var Message:String = "\n\nURL:\n http://localhost/" + Request.Path
+ "\n\nMESSAGE:\n " + Server.GetLastError().Message
+ "\n\nSTACK TRACE:\n" + Server.GetLastError().StackTrace;
// Create event log if it does not exist
var LogName:String = "Application";
if (!EventLog.SourceExists(LogName)) {
EventLog.CreateEventSource(LogName, LogName);
}
// Insert into event log
var Log:EventLog = new EventLog();
Log.Source = LogName;
Log.WriteEntry(Message, EventLogEntryType.Error);
}
|
| C# |
VB |
JScript |
|
上述示例的完整源代码如下。注意:此代码被禁用以便它不能在这里运行,这样可防止向 Windows 事件日志写入项。如果希望看到此代码的运行情况,请创建一个指向包含此文件的目录的 IIS 虚拟根。
- 错误分为四类:配置错误、分析错误、编译错误和运行时错误。
- 默认情况下,为运行时错误显示的信息是调用堆栈(导致异常的过程调用链)。如果启用了调试模式,ASP.NET 将显示源代码中发生运行时错误的行号。
- ASP.NET 使您能够指定是向本地客户端、远程客户端还是这两者显示错误。默认情况下,仅向本地客户端(即服务器所在的同一计算机上的客户端)显示错误。也可以指定自定义错误页,以在发生错误时将客户端重定向到该页。
- 除了将所有的错误重定向到一个公共页外,还可以将特定的错误页分配给特定的错误状态代码。<customerrors> 配置节支持内部 <error> 标记,该标记使 HTTP 状态代码与自定义错误页关联。
- 可以在页级别或者应用程序级别处理代码错误。Page 基类公开了一个 HandleError 方法,此方法在页中可以被重写。每当运行时引发未捕获的异常时都调用此方法。
- System.Web.Mail 命名空间公开以编程方式发送电子邮件的类。这对于在发生错误时通知管理员很有用。
- 除了在页级别处理错误外,还可以使用 Global.asax 中的 Application_Error 事件处理应用程序级别的错误。对于应用程序中引发的任何未处理异常都会引发此事件。
- System.Diagnostics 命名空间提供了写入 Windows 事件日志的类。