ASP.NET中的错误处理有三个方面:
- 跟踪 - 在页面级别或应用程序级别跟踪程序执行。
- 错误处理 - 处理页面级别或应用程序级别的标准错误或自定义错误。
- 调试 - 逐步完成程序,设置断点来分析代码。
在本章中,我们将讨论跟踪,错误处理以及调试。
要理解这些概念,创建一个ASP.Net空网站项目:ErrorHandling 。 它有一个标签控件,一个下拉列表和一个链接。 下拉列表加载名人名言的数组列表,所选引用显示在下面的标签中。它也有超链接,但是指向一个不存在的链接(仅作为示例演示)。参考以下代码(Default.aspx) -
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>ASP.Net错误处理示例</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="lblheading" runat="server" Text="跟踪,调试和错误处理">
</asp:Label>
<br /> <br />
<asp:DropDownList ID="ddlquotes" runat="server" AutoPostBack="True" onselectedindexchanged="ddlquotes_SelectedIndexChanged">
</asp:DropDownList>
<br /> <br />
<asp:Label ID="lblquotes" runat="server">
</asp:Label>
<br /> <br />
<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl="mylink.html">链接到:</asp:HyperLink>
</div>
</form>
</body>
</html>
以下是Default.aspx.cs 的代码 -
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
string[,] quotes =
{
{"Imagination is more important than Knowledge.", "Albert Einsten"},
{"Assume a virtue, if you have it not","Shakespeare"},
{"A man cannot be comfortable without his own approval", "Mark Twain"},
{"Beware the young doctor and the old barber", "Benjamin Franklin"},
{"Whatever begun in anger ends in shame", "Benjamin Franklin"}
};
for (int i = 0; i < quotes.GetLength(0); i++)
ddlquotes.Items.Add(new ListItem(quotes[i, 0], quotes[i, 1]));
}
}
protected void ddlquotes_SelectedIndexChanged(object sender, EventArgs e)
{
if (ddlquotes.SelectedIndex != -1)
{
lblquotes.Text = String.Format("{1}, 名言: {0}", ddlquotes.SelectedItem.Text, ddlquotes.SelectedValue);
}
}
}
运行上面示例代码,得到以下结果 -
跟踪
要启用页面级别跟踪,需要修改Page
指令并添加Trace
属性,如下所示:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" Trace ="true"%>
现在当执行这个文件时,就会得到以下跟踪信息:
它在顶部提供以下信息:
- 会话ID
- 状态码
- 请求时间
- 请求类型
- 请求和响应编码
每次请求页面时,服务器发送的状态码显示错误的名称和时间(如果有的话)。 下表显示了常见的HTTP状态代码:
状态码 | 描述 |
---|---|
100 | 继续 |
101 | 切换协议 |
200 | 完成 |
204 | 无内容 |
301 | 永久转移 |
305 | 使用代理 |
307 | 临时重定向 |
400 | 错误的请求 |
402 | 需要抵消 |
404 | 未找到 |
408 | 请求超时 |
417 | 未实现预期 |
500 | 内部服务器错误 |
503 | 服务不可用 |
505 | HTTP版本不受支持 |
在顶级信息下面有Trace
日志,提供页面生命周期的细节。它提供自页面初始化以来经过的时间(秒)。如下图所示 -
下一个信息块是控制树,它以分层的方式列出页面上的所有控件:
最后在会话和应用程序状态摘要,Cookie和标题集合之后列出所有服务器变量。
跟踪对象允许将自定义信息添加到跟踪输出。 它有两个方法来完成这个操作:Write
方法和Warn
方法。
更改Page_Load
事件处理程序以使用Write
方法记录程序执行过程:
Trace.Write("页面已经开始加载...");
if (!IsPostBack)
{
Trace.Write("Not Post Back, Page Load");
......
运行观察效果:
要使用Warn
方法,可在选择的索引更改的事件处理程序中强制输入一些错误的代码:
// 强制抛出错误
try
{
int a = 0;
int b = 9 / a;
}catch (DivideByZeroException e1)
{
Trace.Warn("UserAction", "processing 9/a", e1);
}
Try-Catch
是一个C# 编程结构。 try
块保存任何可能产生错误或者不产生错误的代码,catch
块捕获错误。 程序运行时,会在跟踪日志中发送警告。
应用程序级别跟踪适用于网站中的所有页面。 它通过在web.config
文件中放入以下代码行来实现:
<system.web>
<trace enabled="true" />
</system.web>
错误处理
虽然ASP.NET可以检测到所有的运行时错误,但仍然有一些细微的错误。 通过跟踪观察错误是为了方便开发人员发现程序问题,而不是为了用户。
因此,为了截获这种情况,可以在应用程序的web.config
文件中添加错误处理设置。 这是应用程序范围的错误处理。 例如,可以在web.config
文件中添加以下行:
<configuration>
<system.web>
<customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.html">
<error statusCode="403" redirect="NoAccess.html" />
<error statusCode="404" redirect="FileNotFound.html" />
</customErrors>
</system.web>
<configuration>
<customErrors>
部分可能有的属性:
- Mode - 它启用或禁用自定义错误页面。它有三个可能的值:
- On - 显示自定义页面。
- Off - 显示ASP.NET错误页面
- remoteOnly - 它向客户端显示自定义错误,在本地显示ASP.NET错误。
- defaultRedirect - 它包含在未处理的错误情况下显示的页面的URL。
为了针对不同类型的错误放置不同的自定义错误页面,根据错误的状态代码使用<error>
子标记,其中指定了不同的错误页面。
要实现页面级错误处理,可以修改Page
指令:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs"
Inherits="errorhandling._Default" Trace ="true" ErrorPage="PageError.html" %>
由于ASP.NET调试本身是一个重要的主题,因此在接下来的教程中,将在单独一篇文章讨论它。