【问题标题】:Good error handling practice良好的错误处理实践
【发布时间】:2010-09-14 09:19:03
【问题描述】:

对于 asp.net 站点,什么是好的错误处理实践?例子?谢谢!

【问题讨论】:

    标签: asp.net error-handling


    【解决方案1】:

    与任何 .net 项目一样,我发现最好的方法是只捕获特定的错误类型,如果它们可能发生在给定的页面上。

    例如,您可以为给定输入的用户捕获格式异常(以防 JavaScript 验证失败并且您没有使用 tryparse),但始终将顶级异常的捕获留给全局错误处理程序。

         try
            {
                //Code that could error here
            }
            catch (FormatException ex)
            {
                //Code to tell user of their error
                //all other errors will be handled 
                //by the global error handler
            }
    

    如果需要,您可以使用 ASP.Net 的开源 elmah(错误记录模块和处理程序)来为您执行顶级/全局错误捕获。

    使用elmah,它可以创建一个错误日志,通过一个简单的配置网络界面可以查看。您还可以过滤不同类型的错误,并为不同的错误类型拥有自己的自定义错误页面。

    【讨论】:

      【解决方案2】:

      我发现一个特别有用的做法是创建一个通用错误页面,然后将 web.config 的 customErrors 节点上的 defaultRedirect 设置为该错误页面。

      然后设置您的 global.asax 以记录所有未处理的异常,然后将它们(未处理的异常)放在某个类的静态属性中(我有一个名为 ErrorUtil 的类,具有静态 LastError 属性)。然后,您的错误页面可以查看此属性以确定要向用户显示的内容。

      更多详情:http://www.codeproject.com/KB/aspnet/JcGlobalErrorHandling.aspx

      【讨论】:

      • 我们对所有未处理的异常做同样的事情。
      • 这听起来非常不安全,给定 HttpContext.Current.Server.GetLastError() 的值值得怀疑,当然在 .NET2.0 中有重定向 200 代码问题
      • 这听起来确实是线程不安全的,但我不使用足够高的流量应用程序来担心它。如果您使用的是流量较高的东西,这可能是个问题。
      【解决方案3】:

      嗯,这是非常开放的,这非常酷。我给你推荐一个word .doc,你可以从Dot Net Spider 下载,它实际上是我小公司代码标准的基础。该标准包括一些非常有用的错误处理技巧。

      一个这样的例外示例(我不记得这是文档的原始内容还是我们将其添加到文档中): 永远不要“捕获异常,什么也不做”。如果你隐藏一个异常,你永远不会知道异常是否发生。您应该始终尝试通过以编程方式检查所有错误情况来避免异常。

      不该做的例子:

      try
      {
         ...
      }
      catch{}
      

      除非你有充分的理由,否则非常顽皮。

      【讨论】:

        【解决方案4】:

        您应该确保可以捕获应用程序生成的大部分错误并向用户显示友好的消息。但当然,您无法捕获所有错误,因为您可以使用 web.config 和 defaultRedirect 由另一个用户。另一个非常方便的记录错误的工具是 ELMAH。 ELMAH 将记录您的应用程序生成的所有错误,并以非常易读的方式显示给您。在您的应用程序中插入 ELMAH 就像在 web.config 文件中添加几行代码并附加程序集一样简单。您绝对应该尝试一下 ELMAH,它确实可以为您节省数小时的痛苦。

        http://code.google.com/p/elmah/

        【讨论】:

          【解决方案5】:
          1. 在每个页面中针对您预期可能发生的异常进行防御性编码并适当地处理它们,这样就不会在每次发生异常时都扰乱用户。

          2. 记录所有异常,并提供参考。

          3. 为任何未处理的异常提供通用错误页面,该页面提供了用于支持的参考(支持可以从日志中识别详细信息)。不要显示实际的异常,因为大多数用户不会理解它,但它会暴露有关您系统的信息(可能是密码等),因此存在潜在的安全风险。

          4. 不要捕获所有异常并且对它们不做任何事情(如上面的答案)。这样做几乎没有充分的理由,有时您可能想要捕获特定异常而不是故意这样做,但这应该明智地使用。

          【讨论】:

            【解决方案6】:

            将用户重定向到标准错误页面并不总是一个好主意。如果用户正在处理表单,他们可能不希望被重定向离开正在处理的表单。我将所有可能导致异常的代码放在 try/catch 块中,并在 catch 块中吐出一条警告消息,提醒用户发生错误,并将异常记录在数据库中,包括表单输入、查询字符串等等。不过,我正在开发一个内部站点,所以大多数用户在遇到问题时都会给我打电话。对于公共站点,您可能希望使用 elmah 之类的东西。

            【讨论】:

              【解决方案7】:
              public string BookLesson(Customer_Info oCustomerInfo, CustLessonBook_Info oCustLessonBookInfo)
                  {
                      string authenticationID = string.Empty;
                      int customerID = 0;
                      string message = string.Empty;
                      DA_Customer oDACustomer = new DA_Customer();
              
                      using (TransactionScope scope = new TransactionScope())
                      {
                          if (oDACustomer.ValidateCustomerLoginName(oCustomerInfo.CustId, oCustomerInfo.CustLoginName) == "Y")
                          {
                              // if a new student
                              if (oCustomerInfo.CustId == 0)
                              {
                                  oCustomerInfo.CustPassword = General.GeneratePassword(6, 8);
                                  oCustomerInfo.CustPassword = new DA_InternalUser().GetPassword(oCustomerInfo.CustPassword, false);
                                  authenticationID = oDACustomer.Register(oCustomerInfo, ref customerID);
                                  oCustLessonBookInfo.CustId = customerID;
                              }
                              else // if existing student
                              {
                                  oCustomerInfo.UpdatedByCustomer = "Y";
                                  authenticationID = oDACustomer.CustomerUpdateProfile(oCustomerInfo);
                              }
                              message = authenticationID;
                              // insert lesson booking details
                              new DA_Lesson().BookLesson(oCustLessonBookInfo);
                          }
              
                          else
                          {
                              message = "login exists";
                          }
                          scope.Complete();
                          return message;
                      }
              
                  }
              

              【讨论】:

              • 您没有提供任何解释说明此代码块如何或为何与所提出的问题相关。
              猜你喜欢
              • 2012-01-15
              • 2018-10-10
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-01-10
              • 1970-01-01
              • 1970-01-01
              • 2011-07-29
              相关资源
              最近更新 更多