这天很开心,终于把自定义异常处理的原理搞明白,还做了出来,现在做一做笔记,还可以温故知新。
主要是这几个动作:
1、先做个xml,用来存储异常信息。文件名:MsgsResource.xml
<?xml version="1.0" encoding="utf-8" ?>
<messages>
<message id="0">
<title>数据提供问题</title>
<body>没有找到数据的提供地方</body>
</message>
<message id="1">
<title>地址错误</title>
<body>页面地址错误或者地址参数错误</body>
</message>
</messages>
2、再做一个用来存msgs的用来存title和body的构造体,类名为CustomExceptionType.cs
public class ExceptionMsg

{
private int messageid=-1;
private string title="";
private string body="";

public int MessageId

{

get
{ return messageid; }

set
{ messageid=value; }
}

public string Title

{

get
{ return title; }

set
{ title=value; }
}

public string Body

{

get
{ return body; }

set
{ body=value; }
}
}
然后再做个读xml的类,这个类要传个id的参数进去作为查找。类名:ExceptionMsgsManager.cs
public ExceptionMsgsManager()

{
//如果Cache为空的话才执行
if (HttpRuntime.Cache["ExceptionMsgs"] == null)

{
Hashtable MsgsTable=new Hashtable();//定义一个哈希表用来存储错误信息的集合
ExceptionMsg em;

XmlDocument doc=new XmlDocument();
string XmlPath=HttpContext.Current.Server.MapPath("MsgsResource.xml");
doc.Load(XmlPath);
XmlNode UrlsRoot=doc.SelectSingleNode("messages");
foreach (XmlNode node in UrlsRoot.ChildNodes)

{
em=new ExceptionMsg();

//用数据构造体装载xml的内容
em.MessageId=int.Parse(node.Attributes["id"].Value);
em.Title=node.SelectSingleNode("title").InnerText;
em.Body=node.SelectSingleNode("body").InnerText;

//将填充好的em加载到哈希表里
MsgsTable[em.MessageId]=em;
}
//将完整的哈希表插入到Cache
HttpRuntime.Cache.Insert("ExceptionMsgs", MsgsTable , null, DateTime.MaxValue, TimeSpan.Zero);
}
}


/**//// <summary>
/// 读取异常信息的Hashtable
/// </summary>
/// <param name="MessageId">这个是xml中的messageid</param>
/// <returns></returns>
public ExceptionMsg GetExceptionMsg(int MessageId)

{
Hashtable Msgs=(Hashtable)HttpRuntime.Cache["ExceptionMsgs"];
return (ExceptionMsg)Msgs[MessageId];
}
3、做一个友好的界面,也就是做一个输出错误信息的页,pageload的事件里就request出地址参数,文件名:WebForm1.aspx
private void Page_Load(object sender, System.EventArgs e)

{
int msgid=int.Parse(Request["msgid"]);
//GetExceptionMsg我将他做成了静态方法,大家可以自己做一个静态方法,且这个页很简单,我就不详细写了
Response.Write(GetExceptionMsg(msgid).Title);
Response.Write("<br>");
Response.Write(GetExceptionMsg(msgid).Body);
}
4、关键的东西开始了~要认真看哦,首先自定义一个异常的枚举类型,类型名:CustomExceptionType.cs
public enum CustomExceptionType

{
DataProvider = 0,//数据提供错误
PageUrlError = 1//地址错误
}
5、然后要写一个自定义的异常处理类,在这个类的重写方法全用自定义的异常类型,这个类继承了ApplicationException,再多态了一下。(这个我想是写注析的,但后来不知道怎样写好,只会让大家意会了)类名:CustomException.cs
public class CustomException : ApplicationException

{

成员#region 成员

CustomExceptionType exceptionType;

public CustomExceptionType ExceptionType

{
get

{
return exceptionType;
}
}

#endregion


构造函数#region 构造函数

public CustomException(CustomExceptionType t) : base()

{
Init();
this.exceptionType = t;
}

public CustomException(CustomExceptionType t, string message) : base(message)

{
Init();
this.exceptionType = t;
}

public CustomException(CustomExceptionType t, string message, Exception inner) : base(message, inner)

{
Init();
this.exceptionType = t;
}

#endregion


重写的方法#region 重写的方法

public override string Message

{
get

{
// 具体处理可以放在这里
// switch (exceptionType)
// {
// case CustomExceptionType.UserNotFound:
// return string.Format(ResourceManager.GetString("Exception_UserNotFound"), base.Message);
// }
return base.Message;
}
}

public override int GetHashCode()

{
string stringToHash = ( exceptionType + base.Message);

return stringToHash.GetHashCode();
}

#endregion


错误产生的属性#region 错误产生的属性
string userAgent = string.Empty;
public string UserAgent

{

get
{ return userAgent; }

set
{ userAgent = value; }
}

public int Category

{

get
{ return (int) exceptionType; }

set
{ exceptionType = (CustomExceptionType) value; }
}

string ipAddress = string.Empty;
public string IPAddress

{

get
{ return ipAddress; }

set
{ ipAddress = value; }
}

string httpReferrer = string.Empty;
public string HttpReferrer

{

get
{ return httpReferrer; }

set
{ httpReferrer = value; }
}

string httpVerb = string.Empty;
public string HttpVerb

{

get
{ return httpVerb; }

set
{ httpVerb = value; }
}

string httpPathAndQuery = string.Empty;
public string HttpPathAndQuery

{

get
{ return httpPathAndQuery; }

set
{ httpPathAndQuery = value; }
}

DateTime dateCreated;
public DateTime DateCreated

{

get
{ return dateCreated; }

set
{ dateCreated = value; }
}

DateTime dateLastOccurred;
public DateTime DateLastOccurred

{

get
{ return dateLastOccurred; }

set
{ dateLastOccurred = value; }
}
int frequency = 0;
public int Frequency

{

get
{ return frequency; }

set
{ frequency = value; }
}

string stackTrace = string.Empty;
public string LoggedStackTrace

{
get

{
return stackTrace;
}
set

{
stackTrace = value;
}
}

int exceptionID = 0;
public int ExceptionID

{
get

{
return exceptionID;
}
set

{
exceptionID = value;
}
}
#endregion


异常产生后要做的事情#region 异常产生后要做的事情

private void Init()

{
//这里暂时为空,要用到的时候再写
}

#endregion
}
6、在Global.asax的Application_Error中做抛出错误后的处理
//先判断是否为自己定义的异常
if(Server.GetLastError().GetBaseException() is CustomException)

{
//把抛出的异常的信息读出来
CustomException ce=(CustomException)Server.GetLastError().GetBaseException();
//带上异常信息的ID跳到错误页
Response.Redirect("webform1.aspx?msgid="+ce.ExceptionID,true);
}
7、最后的一步....测试
try

{
//随便写点东西
SqlConnection conn=........;
conn.Open();
}
catch

{ //没什么好说的,就是势出刚才的劳动成果
throw new CustomException(CustomExceptionType.DataProvider) ;
}
总结:也没有什么好说的,关键是继承ApplicationException那里,在那里最主要明白异常触发的原理,不明白的话也无法解释,明白了也不用解释,就这样...呵呵
其实这个是我的一个笔记,关键原理上的东西我还是刚刚掌握,很难表达出来,日后有机会再写