在ASP.NET MVC 3中自定义错误处理的权威性准则是什么?


44

在ASP.NET MVC(本例中为3)中执行自定义错误处理的过程似乎被忽略了。我已经在网上阅读了各种问题和解答,在各种工具(例如Elmah)的帮助页面上都找到了答案,但是我感觉自己走了一个完整的圈子,但仍然没有最好的解决方案。在您的帮助下,也许我们可以为错误处理设定新的标准方法。我想保持简单,而不是过度设计。

这是我的目标:

对于服务器错误/异常:

  1. 在开发人员中显示调试信息
  2. 在生产中显示友好的错误页面
  3. 记录错误并将其通过电子邮件发送给生产中的管理员
  4. 返回500 HTTP状态代码

对于404 Not Found错误:

  1. 显示友好的错误页面
  2. 记录错误并将其通过电子邮件发送给生产中的管理员
  3. 返回404 HTTP状态代码

是否可以通过ASP.NET MVC实现这些目标?


2
我希望将这个问题迁移回原来的版本,这样它可以获得更多答案。我正在寻找编码答案。
肖恩·麦克林

@Shawn这不太可能发生。这里的问题更多的是主题问题,而不是SO的问题,并且这个问题得到了公认的答案。由于技术原因,问题通常也不会重新迁移。如果您需要有关编码特定错误处理方法的帮助,请在StackOverflow上打开一个新问题。否则,“编码答案”可能是太宽泛的标准,无法使用或无法回答。最后但并非最不重要的是,引起主持人对问题的关注的最佳方法是对其进行标记。您的评论在这里有可能会一直被忽视,如果它没有通过推动评论数超过20跳闸自动标志
亚当利尔

这里过去大约有10条评论,它们都去哪儿了?
RyanW 2011年

我找到了符合您目标的解决方案。我把它作为SO另一个答案:stackoverflow.com/questions/6508415/...
杰西·韦伯

1
@AnnaLear我同意肖恩的观点。我只能通过Google找到此页面。请注意,以下几乎所有答案均包含指向BACK的链接。对我来说,说话很重要,因为它应该首先放在那里。
丽贝卡

Answers:


23

我将分享我最终完成此操作的方式,这是原始问题的一部分。

首先,我遇到的问题:

  1. 启用customErrors(即在生产环境中)时,全局HandleError属性将吞下异常并呈现错误视图,但是由于elmah从未看到过,因此您无法使用elmah之类的插件工具对其进行记录。我想您可以将其记录在您的视图中,但这是一个视图,这似乎是错误的。全局HandleError属性在MVC 3 RTM Visual Studio项目模板中显示为新。

  2. MVC端点的带有URL的customErrors返回302状态代码。有redirectmode属性,但是您不能匹配customErrors中的mvc url并使用ResponseRewrite模式。(https://stackoverflow.com/questions/781861/customerrors-does-not-work-when-setting-redirectmode-responserewrite/3770265#3770265

  3. 完全避免customErrors并处理应用程序中的所有自定义项会导致很多复杂性,IMO。(喜欢这个:https ://stackoverflow.com/questions/619895/how-can-i-properly-handle-404s-in-asp-net-mvc/2577095#2577095 ,但这不适合我们的项目)

我的解决方案

我已经完全排除了MVC。我已删除HandleErrorAttributeglobal.asax中的全局过滤器,并完全专注于customErrors配置,将其转​​移为使用WebForm重定向,并更改为redirectmode ResponseRewrite以避免302 HTTP响应代码。

<customErrors mode="On" defaultRedirect="/Error.aspx" redirectMode="ResponseRewrite">
  <error statusCode="404" redirect="/NotFound.aspx" />
</customErrors>

然后,在NotFound.aspxpage_load事件中,将设置Response.StatusCode为404,在Error.aspx中将代码设置为500。

结果:

两者的目标都可以通过Elmah日志,友好的错误页面和状态代码以及后面的一行代码来实现。我们没有像早期的解决方案那样使用“ MVC方式”,但是如果是两行代码,我可以接受。


5

我认为MVC,ASP和您喜欢的日志记录/异常处理框架可以很好地处理您的目标。ELMAH和Enterprise Library都提供了易于使用的异常处理和日志记录,因此请选择您喜欢的..在这里,我将不讨论它们的优缺点。

注意:您无法显示友好的错误页面,并且无法按照您的问题提示返回HTTP 404或500。返回友好错误页面时,返回到浏览器的HTTP代码为302。这是重定向到友好错误页面的重定向。

友好错误页面

听起来,可以通过ASP.net完善的'ol流行的web.config设置来实现自己的目标一段时间。您提到在开发中显示调试信息,并在生产中显示友好页面。您可以为此使用web.config的“自定义错误”部分(设置CustomErrors =“ Off”以显示调试信息)。我将假设您熟悉CustomErrors属性,如果不阅读,请阅读以下内容:

http://msdn.microsoft.com/zh-CN/library/h0hfz6fc.aspx

如果您需要控制显示的错误视图的粒度,请使用MVC的HandleError属性。这样,您可以为每个操作/控制器选择不同的错误视图。

http://weblogs.asp.net/scottgu/archive/2008/07/14/asp-net-mvc-preview-4-release-part-1.aspx

异常记录

听起来您想以相同的方式响应所有异常(“记录错误并将其通过电子邮件发送给生产中的管理员”)。如果是这种情况,最简单的选择是将代码添加到

Application_Error(对象发送者,EventArgs e)

在您的global.asax中。在这里,您可以转到所选的日志记录框架。

如果要对异常日志记录/处理进行更多控制,则可以将HandleErrorAttribute子类化并覆盖

OnException(System.Web.Mvc.ExceptionContext filterContext)

这是您可以传递到所选日志记录框架的另一个地方。

https://stackoverflow.com/questions/183316/asp-net-mvc-handleerror

比上面提到的Application_Error技术,它给您更多的控制权。

通常,MVC使您可以很好地控制如何处理错误。如果不需要此控件,则可以使用ASP.net的处理方式,例如在web.config上定义错误页面。


非常感谢您添加您的想法。我认为302状态代码在最初的ASP.NET团队中是糟糕的设计选择。我也将在答案中对此加以说明,有一些选择可以做到这一点。正如您所指出的那样,在MVC世界中似乎有些人完全放弃了customErrors并在应用程序中对其进行处理,以实现更好的可重用性和更好的控制。但是,我在实现这些目标方面取得的成功有限,并且添加了很多看起来更好的代码。我在下面的答案中有更多内容。

我更喜欢重写OnException方法进行日志记录,这样我就可以记录所有内容,即使Ajax调用中发生的错误也不会触发您的Application_Error。
艾丽西亚(Alicia)2013年

@Alicia完整示例代码?
Kiquenet '18
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.