












ASP.NET的错误处理机制
对于一个Web应用程序来说,出错是在所难免的,因此我们应该未雨绸缪,为可能出现的错误提供恰当的处理。事实上,良好的错误处理机制正是衡量Web应用程序好坏的一个重要标准。试想一下,当用户不小心在浏览器输入了错误的URL或者当用户提供了一些信息导致程序出错的时候,如果我们没有对这些情况进行处理,而是任由404或是500的错误页面甚至出错的堆栈信息呈现在用户面前,这无疑会把一些用户给吓跑。所以,在我们开发Web应用程序的时候,应该对错误处理机制有充分的了解。让我们回到ASP.NET上来,先提两个问题让大家思考一下:ASP.NET为我们提供了几种错误处理机制呢?如果同时采用了几种错误处理机制,它们之间是否存在一定的优先级呢?带着这个问题,我们先来看一下我们最常见的Web.Config文件:
<?xml version="1.0"?>
<configuration>
<system.web>
<customErrors mode="On" defaultRedirect="GenericErrorPage.htm">
<error statusCode="403" redirect="Error403.htm" />
<error statusCode="404" redirect="Error404.htm" />
</customErrors>
</system.web>
</configuration>
protected void Application_Error(object sender, EventArgs e) {
Exception objErr = Server.GetLastError().GetBaseException();
Response.Write("Error:" + objErr.Message);
Server.ClearError();
}
在这里,大家要注意最后一句代码Server.ClearError()的使用,为什么要使用这句代码呢?如果不用又会怎样呢?在这里我又先卖个关子。好了,第二种错误处理机制——使用Global.asax中的Application_Error事件处理方法也登台亮相了。以上这两种错误处理方法都可以说是全局性的,一个源自应用程序配置文件,一个则是必须放在应用程序根目录下的Global.asax文件的事件处理方法。与全局相对的就是局部,所以我们很自然的就会想:有没有应用于局部——某个页面的错误处理机制呢?答案是“有的”,而且还有两种————使用ErrorPage属性以及使用Page_Error事件处理方法。对于第一种机制,你几乎可以在任何时候设置ErrorPage属性,从而确定页面发生错误的时候会重定向至哪个页面;对于第二种机制而言,它与Application_Error事件处理方法是很类似的,只不过被触发的时机不同而已。以下是具体的两个例子:
<script language="C#" runat="server">
protected void Page_Load(object sender, EventArgs e) {
this.ErrorPage = "ErrorPage.htm";
}
</script>
protected void Page_Error(object sender, EventArgs e) {
Exception objErr = Server.GetLastError().GetBaseException();
Response.Write("Error:" + objErr.Message);
Server.ClearError(); //
ASP.NET的自定义错误处理类
/*----------------------------------------------------------------
* Copyright (C) BYD-D3IT, all rights reserved.
*
* 文件名 :ErrorManager.cs
* 功能描述:asp.net中统一的错误修理,与本类相配套需要增加一个错误信息显示页面,如error.aspx
*
* 使用说明:. 在Application_Start()中启动定时器(定时清空错误信息):ErrorManager.Instance.Start(),
* 默认小时运行一次,或用ErrorManager.Instance.SetTimerInterval()设置。
* 2. 在Application_Error()中,当发生错误时,保存这个错误信息并转到error.aspx中显示这个错误
* string key = ErrorManager.Instance.AddError();
* Response.Redirect("error.aspx?key=" + key);
* 3. 在error.aspx中通过url传来的key,取得并显示错误信息:
* string err = ErrorManager.Instance.GetError(key)
* err中前个字符是错误发生的时间,后面是错误信息。
* 4. 为了捕捉Session超时的错误,而不是返回Session[key]是null的错误信息,本类增加了GetSession()
* 和SetSession函数来统一管理Session,以后aspx中不能直接读取Session,而必须通过本类来读取。
*
*
* 创建标识:
*
* 修改标识:
* 修改描述:
*
* 修改标识:
* 修改描述:
*----------------------------------------------------------------*/
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections;
///<summary>
/// Summary description for Error
///</summary>
public class ErrorManager
{
private System.Timers.Timer m_timer;
private Hashtable m_htErr;
/**////<summary>
///私有的构造函数
///</summary>
private ErrorManager()
{
this.m_timer = new System.Timers.Timer();
this.m_timer.Enabled = false;
this.m_timer.Interval = 12 * 60 * 60 * 1000; //默认个小时执行一次
this.m_timer.Elapsed += new System.Timers.ElapsedEventHandler(m_timer_Elapsed);
this.m_htErr = new Hashtable();
}
/**////<summary>
///单例模式的接口
///</summary>
public static readonly ErrorManager Instance = new ErrorManager();
/**////<summary>
///设置定时器的频率,单位是毫秒
///</summary>
///<param name="Interval">毫秒</param>
public void SetTimerInterval(int Interval)
{
this.m_timer.Interval = Interval;
}
/**////<summary>
///定时器开始
///</summary>
public void TimerStart()
{
this.m_timer.Enabled = true;
}
/**////<summary>
///定时器结束
///</summary>
public void TimerStop()
{
this.m_timer.Enabled = false;
}
/**////<summary>
///发生了一个错误,把错误信息保存起来,并返回错误的id,便于页面中读取
///</summary>
///<returns>返回错误的id</returns>
public string AddError()
{
string key = Guid.NewGuid().ToString();
string msg = System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
+ HttpContext.Current.Server.GetLastError().GetBaseException().Message;
this.m_htErr.Add(key, msg);
HttpContext.Current.Server.ClearError();
return key;
}
///<summary>
///返回指定Key的错误信息,前个字符是错误发生的时间
///</summary>
///<param name="key">key,是一个guid</param>
///<returns>返回错误信息</returns>
public string GetError(string key)
{
return this.m_htErr[key].ToString();
}
/**////<summary>
///定时在Hashtable中清理错误信息
///</summary>
///<param name="sender"></param>
///<param name="e"></param>
private void m_timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
ArrayList list = new ArrayList();
lock (this.m_htErr)
{
DateTime now = DateTime.Now;
TimeSpan ts;
foreach (string key in this.m_htErr.Keys)
{
//前个字符是错误发生的日期,yyyy-MM-dd HH:mm:ss
string time = this.m_htErr[key].ToString().Substring(0, 19);
ts = now - Convert.ToDateTime(time);
if (ts.TotalMinutes > 20) //把分钟前的错误信息从hashtable中清除
list.Add(key);
}
foreach (string key in list)
{
this.m_htErr.Remove(key);
}
}
}
#region Session操作的封装
/**////<summary>
///取得指定键值的Session
///</summary>
///<param name="key">键值</param>
///<returns>键内容值</returns>
public object GetSession(string key)
{
object val = HttpContext.Current.Session[key];
if (val == null)
throw new Exception("页面超时,请重新登录。");
return val;
}
/**////<summary>
///设置Session
///</summary>
///<param name="key">键值</param>
///<param name="val">键内容</param>
public void SetSession(string key, object val)
{
HttpContext.Current.Session[key] = val;
}
#endregion
}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。