【问题标题】:What's the best way to handle the exceptions and how to deal with them in asp.net处理异常的最佳方法是什么以及如何在 asp.net 中处理它们
【发布时间】:2011-07-06 05:44:51
【问题描述】:

首先,我已经熟悉简单的异常处理语法,但我想问的是处理它们的最佳地点、最佳时间和最佳方法。

我正在构建一个 N 层应用程序。所以我认为 DAL 有时会产生一些错误来处理..我刚刚了解了 SqlException 类,该类是怎么回事?我曾经看到一个处理 SqlException 然后它处理异常的代码!

在了解了实践以及我将在哪里处理它们之后,我计划创建一个连接到数据库并将错误记录在数据库中的方法,以便我可以修复它,但我仍然不知道是什么我应该收集哪些信息来识别整个情况!


我认为异常处理没什么大不了的。但是我时不时地读到一些奇怪的建议——我一直不明白——关于问题 cmets 但没有人能回答我,因为这是一些非常古老的问题!

“不要只是明确地捕捉 例外”

" 使用的代码 应用程序中的更高层必须 总是只抛出异常,从不 担心如何处理它们。”

编辑

Page_Error 事件和Application_Error 怎么样.. 我看到它们是处理错误的好习惯

【问题讨论】:

标签: c# asp.net exception-handling webforms


【解决方案1】:

异常处理是一件大事,为此设计一个好的策略并不简单。

首先,一些一般规则:

  • 当正在运行的代码完全无法继续运行时会发生异常,因此它可能尝试处理一些内部异常但最终失败。想想 TCP 连接:如果一个损坏的数据包到达,这是一个异常,但 TCP 协议可以处理它。如果损坏太多,则会抛出 I/O 或套接字异常
  • 不能总是处理异常。在几乎所有情况下,当您从底层获得异常时,您将无法运行纠正代码。如果您的应用程序依赖于一个数据库并且该数据库处于脱机状态,那么当您收到有关它的异常时,您只能显示一条错误消息
  • 异常可能是意料之外的,并且会暴露设计或实施缺陷。例如,实现缺陷可能是您有一个冗余数据库,但当您无法连接到第一个镜像时,您不会尝试第二个

对于第三点,记录异常并定期分析日志以发现任何异常情况很重要。那么,让我们从具体的答案开始吧。

首先

考虑“处理”异常。当您编写每一行代码时,请考虑可能导致其无法完成的问题,并考虑可能的纠正措施。如果有可能的话。错误信息不是很好的处理方式,这是最新的策略。

不要开始写try-catch(Exception),而是更喜欢特定的异常。如果您需要将字符串解析为数字等,请期待FormatException,如果您需要将Object 转换为您的类型,请期待InvalidCastException

当你写低层时

不要犹豫抛出异常!不要像许多人那样做,即。 return null 或使用(如 ANSI C)布尔返回值和引用参数。有例外。如果你可以处理异常(即你没有找到本地文件但你知道你有一个远程备份,所以通过调用远程镜像来处理FileNotFoundException,但如果你仍然不能连接那么最终抛出)然后这样做并尝试恢复计算,但如果你不能然后抛出。并且不要忘记抛出内部异常(如果存在),因为它有助于登录最高层。

基本上,即使您没有捕获任何异常,您仍然可以自行决定抛出异常!强烈建议这样做,尤其是在函数参数无效时!

另一个不错的选择是仍然登录底层。无论发生异常,您实际上都想记录。

当您登录时

记得给消息提供足够的严重性。如果您通过代码发现您的数据库处于脱机状态,这并非意外异常。仍然将其记录为错误,但在调查日志时不要担心代码错误。相反,如果您捕获到您的代码无法识别的异常(NullReferenceException 是一个经典示例),则以最高严重性记录,即。致命的,给予它最高优先级!

ASP.NET 的好策略

当然可以基于Page.OnError 方法。如果您的站点的所有页面都有一个基页面类,那么您绝对应该重写该方法。在该方法中,您应该首先记录您的异常。

你也不应该滥用 try-catch(Exception) 块,因为如果你没有捕捉到你不能用 catch 处理的异常,你必须通过 OnError 来处理它.

当你运行这样的方法时,不要马上想到Server.RemoveError()。您可以更喜欢为 HTTP 500 错误(当未处理的异常冒泡到 ASP.NET 运行时触发)的静态 HTML 页面,向用户显示礼貌消息。

简述

  1. 如果发生任何奇怪的事情,请不要犹豫在底层throw
  2. 正如您的建议所说,不要处理您无法处理的异常(如果您捕获到您无法处理的异常,请重新抛出它)
  3. 记录!!!!!!!!!!!!!!!!!!
  4. 不要在公共网站上向最终用户透露异常详细信息,千万不要!默认情况下,ASP.NET 会阻止这种情况发生,但您仍然可以使用 OnError 打印堆栈跟踪
  5. 使用OnErrorApplication_Error作为单一中心点来处理所有意外异常
  6. 根据错误/致命消息定期检查日志以发现代码问题,然后考虑维护/调试/修复它

【讨论】:

  • 抱歉 djechelon 没有早点回复..我认为这将是一个比这更容易的任务,我现在不能专注于异常和验证方面..所以当然标记为答案和何时我在我的项目中详细介绍了这一点所以我能理解更多,那太好了谢谢! =)
【解决方案2】:

看看艾玛。它是asp.net 的记录器。在漂亮的摘要页面上呈现所有错误。

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

处理异常的最佳方法是在它们适用的特定层中。如果它是一个约束变化,例如,有 2 个同名用户,你应该让它冒泡到 UI 并提醒用户。

任何违反业务规则的行为也是如此。这些应该冒泡到 UI,以便最终用户知道出了什么问题。

最好在 DAL...等中处理 SQL 连接错误。

【讨论】:

  • 违反业务规则应该是例外吗?
  • log4net 记录到 sql server 也是一个不错的选择。使用 l4n dash 进行报告
  • 克里斯,我希望知道他们在那些现成的第三方模块下真正做了什么,这样我就可以为我的项目构建一个简单而有效的模块! ..你有什么想法或教程来教我吗?以及我应该从异常对象中收集哪些信息来帮助我识别问题,就像发生在我面前一样,这样我就可以解决它!
  • 我同意 Paul btw .. 我认为不应该!
【解决方案3】:

捕获异常的方式/时间/位置可能取决于您尝试准确执行的操作,很难给出准确的捕获所有始终正确的答案。


至于你的具体问题,

我刚刚了解了 SqlException 班,那班是怎么回事 ?我曾经看到一个处理 SqlException 然后它处理 例外!

处理您认为可能发生的特定异常是一种很好的做法,如果您不确定此异常是什么类型,您可以只使用“异常”,如果您希望在“SQLException”上发生特定的事情以及发生其他事情一个“异常”,那么编写处理这两者的代码肯定没有错。


“不要只是明确地捕捉 例外”

我相信这是指这样的代码

try 
{
   int i = 1/0;
} 
catch(Exception e)
{
  //do nothing
}

这个异常会被捕获,但你永远不会知道它发生了,因此这不是一个好主意,使用代码的人会摸不着头脑。

【讨论】:

  • +1 进行澄清,如果我发现它引发的异常,那么我们可能有一个“在哪里”处理它的计划.. 但我仍然应该在我的数据库中捕获什么信息所以我可以了解任何人面临的问题,假设我将在我的所有层中使用 Exception,除了 DLL 我将使用 SqlException 因为我认为这将是这一层中发生的唯一异常!
【解决方案4】:

我认为您在这里要问的是任何应用程序的错误/异常处理策略。

我认为包括:

Where - 您认为可能发生异常或需要更多监控的所有地方,例如数据库调用、外部服务调用、数组的使用、用户输入解析、类型转换等...

如何 - 所有高级层都应该抛出异常,它应该在入口点被捕获并处理以了解根本原因。通常您在 Application_Error() 中执行此操作,您可以在其中捕获异常并将其记录下来以进行故障排除。如何记录异常取决于您。日志文件或数据库驱动的日志是基于您的要求和可用资源的选项。

【讨论】:

  • "并进行处理以了解根本原因。"怎么 =) ?
  • +1 btw .. 一个不错的答案,但我希望你能给我看完整的图片,也许还有一些代码 .. 不是初学者的例子! .. 我想看看它是如何真正实现的(特别是 How 部分!)
【解决方案5】:

IMO 除了极少数情况外,我只对 I/O 相关代码使用异常处理,因为这些代码与服务和文件系统交互,其功能和维护超出了我的应用程序的控制范围。

我一直认为使用 try/catch 语句来操纵程序中的逻辑(控制流),就像 if/else 语句一样是非常糟糕的做法。如果您正确使用手头的工具,则可以避免大多数常见异常。

【讨论】:

  • 对不起 Rob 我没有得到你想说的关于 if/else 的内容,但我当然会努力进行验证并确保不会错过我的系统或代码.. 但是如果我的代码不完美,而且永远不会是.. 当发现错误并引发错误时,我不希望我的系统终止或将访问者赶走!
  • Bug 总是会出现 - 你打算怎么做 - 将你的整个应用程序包装在一个巨大的 try/catch 语句中?如果你对你的代码有足够的了解,知道你需要一个 try/catch 语句,那么你就可以通过检查空对象之类的东西来更优雅地处理错误。
  • @iKashef,错误与异常不同。仅在没有替代方法时才使用 try/catch 是一种很好的做法。例如,您不应该通过用户输入获得异常,您应该能够在异常发生之前对其进行验证。如果您的数据库硬盘驱动器已过期并且有人试图将某些内容保存到数据库中,这是一个您无法控制的异常并且应该被捕获,可能在您的 DAL 中。
猜你喜欢
  • 1970-01-01
  • 2011-04-29
  • 2021-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-04
  • 2012-09-18
  • 1970-01-01
相关资源
最近更新 更多