程序猿刚子的博客

大龄程序猿,分享互联网开发相关知识!前端、后端,架构等内容,欢迎关注公众号 chengxuyuangangzi

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

异常的产生

在.net应用开发中,程序在运行时总会由于一些无法预料的、不合法的客观条件产生问题,抛出异常。如:在类型转换时,将一个非数字型字符转换为整形时;一个引用类型未进行初始化我们却调用它的方法或属性时;io操作时资源未准备好时;数据库操作时,db server无法访问、或者sql出错的时候,等等。 

Asp.Net默认是怎么处理异常的

在产生异常的时候如果我们没有在自己的代码中捕获异常的话,应用程序会将异常信息交给asp.net runtime, 将将会抛出一个HttpUnhandledException异常。就是这个异常报给了我们经常看到的黄页信息。当然,它不只是会报黄页信息而已,也可以根据配置中的信息进行自定义异常页面。

在webconfig配置文件中,<customErrors>该节点定义了HttpUnhandledException这个类的处理行为。不同的行为依赖于customErrors节点的mode属性,共有下面三个属性:

  1. On  对所有用户展示自定义的错误页面或者一个Runtime Error的黄页,不包含错误的详细信息
  2. Off  对所有访问用户暴露出详细的错误信息
  3. RemoteOnly 对非本机用户暴露友好的错误信息。

当我们自定义错误页面的时候,可以这样<customErrors mode="On" defaultRedirect="~/error.aspx" />定义一个错误页面,也可以针对不同的异常类型指定不同的错误页面,如:  

        <customErrors mode="On" defaultRedirect="error.aspx">
            <error statusCode="404" redirect="404.aspx"/>
            <error statusCode="500" redirect="500.aspx"/>
        </customErrors> 

这样产生错误的时候就会根据不同的http码跳转到不同的页面了。

另补充一句:

  1. HttpUnhandledException在针对异常根据不同的配置进行跳转的时候是利用了 Response.Redirect()方法302跳转。
  2. 真对一些静态资源文件的404情况不会被处理,这些是被iis直接处理的。
  3.  

 404了我该做些什么

在发生404的时候有时是我们自己的站点链接写的不正确,或者是来自一些其他站点的错误外链,那么这个时候我们知道该链接来自哪里很重要,所以在404后跳转的页面中我们最好将发生了什么,在哪里发生的告诉自己,并及时的处理。开始在想这个问题的时候我还觉得用urlref获取不到错误页面的来源。后来发现在 Response.Redirect()方法302跳转的时候原始请求的一些信息也是附带过来的。所以打消了这个疑虑。这样我们就可以在404异常处理页面中记录异常来源通知自己了。另外来自一些外站的错误链接,我们不能等待他们修改,我们可以做个错误链接的映射,在404处理页面进行匹配处理。

 404我们获取到死链接的来源了,那么我们如何获取到详细的错误信息呢?

 一个问题是,当我们定义了友好的错误页面后,我们不能获取到详细的错误信息。如:在1.aspx页面发生了异常,将直接回跳转到500.aspx页面中,相当于2个请求,在新的请求当中(302跳转),我们是没有办法获取到前一个页面的信息的。下面看看针对这种情况我们如何处理它。

当一个未处理的异常抛给asp.net runtime时,会激发一个应用程序级别的异常事件,通过在这个事件中获取处理异常,我们可以记录日志,发邮件通知作者,用Server.Transfer()跳转到自定义的错误页面。Transfer不同于Redirect方法,它是在服务端的跳转,会携带着上下文信息,允许跳转的页面访问这些信息。;)

如何在应用程序级别的异常事件中处理异常

HttpApplication应用程序类中包含了一系列的asp.net web 应用程序事件,当一个未被处理的异常发生时就会激发该类的Error事件。在该事件中我们可以通过Server.GetLastError()方法获取发生的异常对象。之后就可以进行异常信息的记录、通知等操作了。在此处我们获取的异常对象是HttpUnhandledException的实例,实际页面发生的异常被该对象封装在里面了,可以通过InnerException属性获取到。

这样我们就可以捕获到应用程序发生的异常信息并且记录、发邮件啊之类的,之后在进行跳转到自定义的有好错误页面。 

        //获取到页面发生的异常对象
        var error = Server.GetLastError();
        if (error is HttpUnhandledException && error.InnerException != null)
        {
            error = error.InnerException;            
        }

        try
        {
            //do something with error infomation
        }
        catch
        {
            
        }
        Server.Transfer("yourcustompage.aspx"); 

用HttpModule方式处理异常事件

为什么要用HttpModule的方式?

这种方式提供了一种更灵活的处理方法,我们可以简单的将dll放到bin目录并且改几句配置文件就可以加入我们的功能,非常灵活自由。

 开源日志库:ELMAH

 

 

 

参考文摘:

http://www.4guysfromrolla.com/articles/090606-1.aspx

http://www.4guysfromrolla.com/articles/091306-1.aspx

posted on 2012-10-24 14:14  程序猿刚子  阅读(636)  评论(0编辑  收藏  举报