65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 XML 和 C#.NET 为 ASP.NET 实现自定义错误处理库

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.38/5 (7投票s)

2010年2月25日

CPOL

3分钟阅读

viewsIcon

47370

downloadIcon

316

使用 XML 处理和跟踪 ASP.NET 中的异常/错误

引言

作为 ASP.NET 开发人员,我们开发一个 Web 项目并在一个月内完成,因为有很多组织在开发网站或 Web 应用程序项目方面有着非常紧张的时间表,并在几个月内将项目交付给客户。 项目交付后,如果客户说他们遇到了问题或应用程序出现错误,那么开发人员测试每件事(甚至有时是整个项目)以查找小错误(这里所说的错误,我们不是在谈论逻辑错误, 我们谈论的是主要负责应用程序中错误的异常)总是让人头疼。 有很多 .NET 框架触发的异常,我们在调试或开发应用程序时从未发现。 这些异常不会直接影响应用程序,但每个小异常都会给服务器带来不必要的负担。 这是跟踪 ASP.NET Web 应用程序内部发生的每件小事的解决方案,我将其命名为“自定义错误跟踪库”。

实现自定义错误处理库

首先出现的问题是它的核心概念是什么。 概念是我们将维护一个具有预定义结构的 XML 文件,我构建了该文件,其中将包含所有必需的字段作为节点和子节点,我们称之为 errorlog.xml。 将有一个 CS 库文件,它将跟踪应用程序或 .NET Framework 内部发生的每一个小错误/异常,并将错误详细信息放入 XML 文件中。 一旦我们准备好 CS 库,我们只需一个简单的函数,该函数有两个重载方法,具体取决于代码的每个 try/catch 块中的要求,以及 Global.asax 文件的 Application_Error 事件。

错误日志记录的 XML 文件结构

<xml version=”1.0? encoding=”utf-8?>
<errorlog>
  <error>
    <datetime>datetime</datetime>
    <filename>filename</filename>
    <classname>classname</classname>
    <methodname>methodname</methodname>
    <errormethod>errormethod</errormethod>
    <message>ErrorMessage</message>
    <errordetails>Details goes here</errordetails>
    <IP>IP address</IP>
    <url>URL</url>
  </error>
</errorlog>  

在 XLM 文件 <errorlog> 的根节点内,将有一个子节点 <error>,该节点将针对每个错误进行复制。 对于每个错误,该库将生成一个带有 XML 文件中所有下面列出的详细信息的节点。 紧挨着最后一个错误节点。 因此,对于每个错误,将有一个单独的错误节点。 上面 XML 文件的每个字段描述如下

  1. Datetime:错误/异常的日期和时间
  2. 文件名:发生异常或错误的文件名
  3. 类名:发生错误的类名
  4. 方法名:出现错误的函数名
  5. 错误方法:包含错误代码的函数名
  6. 消息:错误消息/异常消息
  7. 错误详细信息:详细的错误描述,将显示功能执行的整个堆栈跟踪
  8. IP:客户端 IP 地址
  9. URL:绝对错误 URL

CS 文件中的代码 (errorHandler.cs)

将有一个 CS 库文件,我们将在其中编写所有用于错误处理并将错误写入 XML 文件的功能。 errorHamdler.cs 文件将有两个名为 WriteError()static 方法。 对于相同的功能将有两个具有不同参数的重载方法。 CS 文件将如下所示。 我们将其命名为 errorHamdler.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Reflection;
using System.Diagnostics;
namespace TheCodeCenter
{
    public class errorHandler
    {
        string _strErrorMessage, _strDetails, _strClassName, _strMethodName;
        DateTime _dtOccuranceTime = new DateTime();
        public errorHandler()
        {

        }
        public errorHandler(DateTime time, string className, 
		string methodName, string errorMessage, string details)
        {
            _dtOccuranceTime = time;
            _strClassName = className;
            _strDetails = details;
            _strErrorMessage = errorMessage;
            _strMethodName = methodName;
        }
        public static void WriteError(Exception ex)
        {
            WriteError(ex, "");
        }
        public static void WriteError(Exception ex, string fileName)
        {
            XmlDocument doc = new XmlDocument();
            string strRootPath = System.Configuration.ConfigurationManager.AppSettings
				["logfilepath"].ToString();
            string xmlPath = System.Web.HttpContext.Current.Server.MapPath(strRootPath);
            doc.Load(@xmlPath);
            XmlNode newXMLNode, oldXMLNode;
            oldXMLNode = doc.ChildNodes[1].ChildNodes[0];
            newXMLNode = oldXMLNode.CloneNode(true);

            StackTrace stackTrace = new StackTrace();
            StackFrame stackFrame = stackTrace.GetFrame(1);
            MethodBase methodBase = stackFrame.GetMethod();

            newXMLNode.ChildNodes[0].InnerText = DateTime.Now.ToString();
            newXMLNode.ChildNodes[1].InnerText = fileName;
            newXMLNode.ChildNodes[2].InnerText = methodBase.DeclaringType.FullName;
            newXMLNode.ChildNodes[3].InnerText = methodBase.Name;
            newXMLNode.ChildNodes[4].InnerText = ex.TargetSite.Name;
            newXMLNode.ChildNodes[5].InnerText = ex.Message;
            newXMLNode.ChildNodes[6].InnerText = ex.StackTrace;
            newXMLNode.ChildNodes[7].InnerText = 
		System.Web.HttpContext.Current.Request.UserHostAddress;
            newXMLNode.ChildNodes[8].InnerText = 
		System.Web.HttpContext.Current.Request.Url.OriginalString;
            doc.ChildNodes[1].AppendChild(newXMLNode);
            doc.Save(@xmlPath);
            doc.RemoveAll();
        }
    }
}

Web.Config 设置

<appSettings>
	<add key="logfilepath" value="~/errorHandling/errorlog.xml"/>
</appSettings>

如何在应用程序中使用错误处理程序

现在一切都已准备好在实时应用程序中使用。 在每个 try/catch 块中,我们必须调用 Writeerror() 函数,如下所述

protected void Page_Load(object sender, EventArgs e)
{
    throw new Exception("asds");

    try
    {
        int a = 0;
        int b = 10 / a;
        //throw new Exception("Custom error");
    }
    catch (Exception ex)
    {
        Response.Write(ex.Message);
        TheCodeCenter.errorHandler.WriteError(ex, "Default.aspx.vb");
    }
}

除了每个 try/catch 块,我们也会在 Global.asax 文件中放入一些代码,如下所示

void Application_Error(object sender, EventArgs e)
{
    object a = System.Web.HttpContext.Current.Request.ServerVariables["HTTP_REFERER"];
    TheCodeCenter.errorHandler.WriteError
	(Server.GetLastError().GetBaseException(), "Global.asax");
}

将代码放入 Global.asax 文件的原因非常重要且必要,因为可能有很多异常发生在应用程序级别,并且在任何函数或事件的任何 try/catch 块中都无法跟踪。 因此,除 try/catch 块之外的任何错误都将出现在此事件 (Application_Error) 中,并将插入到 XML 文件中。 就这样,我们完成了错误处理,并且所有错误都可以从通过错误处理程序生成的 XML 文件中跟踪。

© . All rights reserved.