第7章 异常处理和日志追踪
合集下载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
7.1.4 异常的嵌套
假定在try块中调用一个来自外部的方法,比如定义了一个用于除 法运算的函数,在该函数内部捕捉了DivideByZeroException的异 常.然后在另外一个try块中调用这个除法运算的函数,这种方法 称为嵌套异常.下面继续7.1.1节的示例,复制了Button控件和 Label控件,在后置代码中创建二个除法运算的函数,然后在 Button按钮的单击事件中调用这个函数,
第7章 异常处理和日志追踪
在应用程序运行过程中,难免会遇到异常,错误.笔者在 开发过程中经常会被一些用户投拆软件出现故障,或者是 一些乱七八糟的错误提示.用户并不都是专家,看到这些 莫名其妙的错误往往会认为是应用程序不稳定因素所致, 笔者的同事此时会振振有次的告知用户:软件出现故障是 难免的,微软够强大吧,Windows系统还不是会蓝屏出错. 这样的解释并不是没有道理,任何软件都不可能十全十美, 问题在于开发人员如何处理错误,如何让应用程序能够无 缝的从错误中恢复. 本章将讨论如何处理ASP.NET应用程序中的异常,如何追踪 错误以及解决一些故障问题.将会讨论结构化异常处理, 日志记录以及当出现错误时,如何将用户页面重定向到一 个用户友好的提示页面,本章也将介绍如何使用页面追踪 和查看ASP.NET页面的诊断信息.
Hale Waihona Puke Baidu
7.2.2 写入事件日志
System.Diagnostics命名空间下提供了可以读写事件日志 的类,开发人员可以使用这个命名空间中的类将ASP.NET异 常信息写入事件日志中,下面举一个示例演示在ASP.NET中 如何写入事件日志,本示例中将提供一个除法运算输入框, 当运算出现任何异常时,将异常信息写入事件日志. (1)新建一个ASP.NET Web站点,命名为EventLogDemo, 在Default.aspx中添加两个TextBox控件和一个Button与 Label控件,布局效果如图7.13所示. (2)当单击运算按钮时,将从两个文本框中获取数据,并 执行乘法运算.如果运算中有任何异常,则在Label控件中 显示错误信息,并将异常消息写入事件日志,
7.4 页面追踪
尽管ASP.NET的错误页面提供了非常有用的信息, 但是有时候开发人员需要更详细的信息来修正应 用程序中的错误.比如应用程序执行一个属性或 者是追踪应用程序中的逻辑错误.有时候应用程 序可能生成了一些无效的数据,但是并没有明显 的异常触发.ASP.NET提供了追踪功能,让开发人 员使用一种更方便和有弹性的方式来报告诊断信 息.
7.3.1 错误模式
图7.18是笔者在本地机器上产生错误的错误页面,对远程用户来说,则有 不同.出于安全性考虑,通常不希望在远端的用户看到错误页面源代码列 表等.ASP.NET中,可以在web.config配置文件中的<customErrors>配置 节中配置错误页面的显示方式,当开发人员新建一个ASP.NET Web站点时, <customErrors>的配置节如下代码所示. <!-如果在执行请求的过程中出现未处理的错误, 则通过 <customErrors> 节可以配置相应的处理步骤.具体 说来, 开发人员通过该节可以配置 要显示的 html 错误页 以代替错误堆栈跟踪. <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm"> <error statusCode="403" redirect="NoAccess.htm" /> <error statusCode="404" redirect="FileNotFound.htm" /> </customErrors> -->
7.2.3 自定义日志
自定义的日志是指属于自己的分类的日志,比如 可以创建一个属于本程序特有的错误分类.笔者 创建了一个ASPNET35BookDemo的事件分类,如图 所示.
7.2.4 编程查看事件日志
可以使用ASP.NET将事件日志呈现在Web页上,这样系统维 护人员不用必须跑到Web服务上去检查应用程序产生的日志. 下面继续以上一小节中的事件日志为例,为其添加一个显 示指定日志的事件日志项的页面. (1)右击EventLogDemo示例程序,选择"添加新项"菜单 项,在弹出的添加新项窗口中选择"Web窗体"项,命名为 ShowEventLog.aspx,单击确定按钮关闭窗体.在该示例中, 将使用一个GridView控件来显示事件日志信息,因此在设 计视图上从工具箱的数据栏中拖一个GridView控件到页面 上. (2)为了获取事件日志信息,笔者新建了一个名为 myEventLog.cs的类文件,在该文件中创建了一个单表单个 日志项的myEventLog类和代码列表项的LogList类,
7.3 错误页面
错误页面用于描述当前页面中未被处理的错误,当在进行 ASP.NET项目开发时,开发人员将面对大量的错误页面来进 行调试和处理.错误页面对于在开发过程中诊断错误是非 常有用的,因为其中包含了大量关于产生错误的信息.图 7.18显示了一个由笔者故意产生的错误页面,新建一个 ASP.NET Web项目命名为ErrorPageDemo,在Default.aspx 的Page_Load事件中添加如下的程序代码: protected void Page_Load(object sender, EventArgs e) { //直接抛出一个未经处理的异常,由ASP.NET显示 一个错误信息页面 throw new Exception("错误页面"); }
7.1 ASP.NET应用程序异常处理
错误的产生很多时候是开发人员始料未及的,有的错误可 能运行了很久才突然被触发.然而也有一些错误是由于开 发人员的疏漏所造成的,一个简单的例子是被0除.假如在 一个具有很多复杂公式的页面上,要求用户输入有效的数 据执行计算,由于没有很好的验证机制,用户如果一不小 心输入了一个0作为被除数,ASP.NET将跳转到一个错误页 面,如图所示.
7.3.2 自定义错误页面
在7.3.1节中列出的由VS2008生成的 <customErrors>节的代码中,还具有两个非常有 用的<error>子节点.该节点指定当发生指定的错 误时,将页面重定向到一个定义好的错误页面. 比如当发生403错误时,将页面重定向到 NoAccess.htm页面. 当然开发人员不可能为所有的错误都单独创建一 个错误页面,这将是一个非常巨大的工程.并且 IIS己经为Web应用程序中的错误提供了多个错误 的页面,
7.1.3 捕捉异常
通常使用try/catch语句块来捕捉异常,如7.1.1节中的例子所示. 当使用catch语句捕捉到一个异常时,都是一个具体类型的异常而 不是一个Exception这样的异常基类,具体异常用于描述一个指定 类型的错误,例如上一节中的DivideByZeroException异常. 在捕捉异常时,可以定义多个catch块,但是只能有一个try块, 这一节继续7.1.1节中的示例,将Button1中的单击事件更改为如 下的代码:
7.1.6 Finally语句块
不论是否捕捉到异常,finally块中的代码一定会 执行.举个例子,在处理文件时,如果打开了一 个文件,执行一些写入操作,这时发生了致命错 误,由于catch块捕捉到异常后,控制权会直接跳 转到异常处理结尾,那么,这时这个打开的文件 便一直没有被关闭.显然这会造成资源占用,如 果文件是以独占的方式被打开的话,其他操作将 无法顺利进行. 另外一个比较常见的例子是数据库操作,如果正 在执行一个行级锁定更新时,发生了异常,那么, 这会导致这个锁一直不能被释放,继而影响到其 余的步骤无法顺利进行.
7.1.2 Exception类
上一节的示例中,当产生了被零除的错误后,.NET会创建一个名为 DivideByZeroException的异常对象,catch块中将捕获这个异常对象,并 执行处理异常的代码块.DivideByZeroException是一个派生自Exception 的对象.Exception对象中包含了很多有用的关于异常的信息,如上面示 例中的Message属性用于获取异常的描这性信息,表中列出了Exception类 中的一些成员描述.
7.1.1 异常处理基础
大多数.NET语言都支持结构化异常处理,当一个错误引发 时,.NET框架其实创建了一个异常对象用于呈现问题.开发人员 可以使用异常处理器来捕捉这个异常对象.假如不使用异常处理 器的话,用户代码将会被中止,ASP.NET将显示一个让用户迷惑的 错误处理页面. 为了演示如何使用结构化的异常处理,本小节创建一个异常处理 程序命名为CommError.在Default.aspx页面上添加一个Button控 件,为该Button添加一个单击事件,代码如下所示. protected void Button1_Click(object sender, EventArgs e) { int x = 5; int y = 0; //故意被0除,产生一个异常 int z = x / y; }
Exception的成员描述 属 性 Message Data Source StackTrace TargetSite HelpLink InnerExceptoin 类 型 String IDictionary String String MethodBase String Exception 描 述 描述错误的可读文本.当异常发生时,运行库产生文本消息,通知用户错误的性质, 并提供解决该问题的操作建议 使用由 Data 属性返回的 System.Collections.IDictionary 对象来存储和检索与异常相 关的补充信息 产生异常的程序集的名称 发生异常时调用堆栈的状态.StackTrace 属性包含可以用来确定代码中错误发生位 置的堆栈跟踪,对于调试来说,这是非常有用的信息 抛出异常的方法 获取或设置异常的关联帮助文件的链接 创建对以前的异常进行捕捉的新异常.处理第二个异常的代码可利用前一个异常的 其他信息更适当地处理错误.如果不存在前一个异常,则为null
7.1.5 自定义异常
如果系统提供的异常类已经不能够满足应用系统 开发的需要,或者开发团队需要一套自定义异常 处理机制,可以创建自定义的异常类. 为创建自定义异常类,应该直接或间接地继承自 ApplicationException类.自定义异常类应该有 良好的命名,一般建议的名称是:错误的描述性 名称+Exception.自定义异常类应该定义三个构 造函数:默认构造函数,接收错误消息的构造函 数,接收错误消息和内部异常对象的构造函数.
7.2 记录异常
Web应用程序的用户可能成千上万,有些时候除了 向用户显示错误信息之外可能还需要将异常记录 下来,比如Web服务器负载过重,一些问题间歇性 的多次出现等等..NET框架提供了多种日记志工 具,比如可以在错误产生时发送E-Mail,添加到 数据库记录或者是读写文件.一个较好的处理方 式是使用Windows事件,Windows事件程序是 Windows内置的用于记录系统或者是应用程序日志 的一个工具.这个工具可以被任何应用程序使用.
7.2.1 查看Windows事件日志
启动Windows事件查看器,点击"开始|设置|控制面板|管 理工具"菜单,选择事件查看器,将弹出如图7.9所示的事 件查看器窗口. 事件查看器在不同的系统中可能有些不同,系统内置的事 件分类有应用程序,安全性,和系统,如果是Windows Vista或者是Windows Server 2008,还多了一个安装分类, 这些日志类型的说明如下: 应用程序:用于记录任何应用程序的错误或者是通知,异 常通常在可以在应用程序日志中记录ASP.NET应用程序异常. 安全:用于记录安全相关的问题,仅由操作系统使用. 系统:用于记录跟操作系统相关的事件. 安装:用于记录安装Windows更新或者是安装其他软件,在 Windows Vista中可用.