了解 ASP .NET (WebForms) 中的错误处理

Understanding error handling in ASP .NET (WebForms)

我有一个 Web 表单 (.NET 4.0) Web 应用程序构建为:

  • MyApp.Portal(包含页面、WCF AJAX 服务、脚本等的主门户)
  • MyApp.BusinessLayer(Class库调用DataAccess获取数据)
  • MyApp.Services(Class 库包含用于服务器端代码的 WCF 服务器)
  • MyApp.DataAccess(ADO 甲骨文)

    我正在尝试遵循一些关于错误处理的教程,但到目前为止我得到的结果不一致。

    我的问题是我应该如何处理应用程序中的错误?
    我应该将所有方法包装在 try/catch 中吗?
    我应该只用 try/catch 包装业务层中的方法吗?
    我将如何使用 WCF Ajax 方法处理 PortalLayer 中发生的错误?

    例如,我将以下内容添加到我的 Global.asax 文件中:

    void Application_Error(object sender, EventArgs e)
            {
                // Code that runs when an unhandled error occurs
                Exception exc = Server.GetLastError();
    
                if (exc is HttpUnhandledException)
                {
                    if (exc.InnerException != null)
                    {
                        exc = new Exception(exc.InnerException.Message);
                        Server.Transfer(@"\Pages\Error.aspx?handler=Application_Error%20-%20Global.asax", true);
                    }
                }
    
            }
    

    但是大多数时候这不会被调用。我只是看到错误消息显示在屏幕上(就像一个美化的警报)。
    或者,如果调用此方法,则 exc 不是 HttpUnhandledException,因此传输永远不会发生。

    我也在我的 web.config 中尝试过这个,但我没有看到它有任何作用。 (如果我将其注释掉,我会得到相同的结果)

    <customErrors mode="On" defaultRedirect="Error.aspx?handler=customErrors%20section%20-%20Web.config">
      <error statusCode="404" redirect="ErrorPage.aspx?msg=404&amp;handler=customErrors%20section%20-%20Web.config"/>
    </customErrors>
    

    最终目标是将用户重定向到一个页面(或者可能只是很好地显示错误),同时将其记录在文件中或将错误写入数据库。

  • 当服务器处理页面(请求 .aspx、.ashx 资源)时,主线程中发生的异常将调用 void Application_Error(object sender, EventArgs e)

    在两种情况下不会被调用:

    • 您在处理 .aspx 资源时触发了新线程,异常将在该新线程中发生
    • 在网络服务方法、wcf 方法等中(即非 .aspx 资源)
    • 异常是 "bad ass" 异常 - 破坏应用程序域的那种 - WhosebugExceptionOutOfMemoryException

    因此对于 WCF、WebServices 来说,将所有入口点包装在

    中是有意义的
    try {} 
    catch(Exception e) {
      Logger.Log(e);
      throw;
    } 
    

    声明(请注意,如果您有很多这样的声明,请花时间研究更通用的解决方案)。

    另请注意 - 如果您的错误页面上有错误,您将看到黄屏死机(很明显)。所以我更喜欢将静态 html 页面显示为错误页面(出错的可能性最低)。

    在您的错误处理代码中,您没有清除错误状态,而且我更喜欢 Redirect 而不是 Server.Transfer 来进行错误处理。最终剪辑看起来像:

     var ex = Server.GetLastError();
     Logger.Log(ex);
     Server.ClearError();
     Response.Redirect("/error.aspx");
    

    最后说明 - 无需自己进行错误记录(优秀的程序员很懒惰 - 就“不要重新发明轮子”而言) - 有很多很棒的日志记录模块,如 Elmah、Microsoft Enterprise Library 或 log4net。