/*十有三博客*/
  • 首页
  • 关于本站
  • 网站地图
  • RSS订阅

ASP.NET MVC全局异常处理和捕获的思路

2015-12-05 十有三 0 浏览:5362 .NET技术 ASP.NET MVC

这几天稍微研究了下ASP.NET MVC的全局异常处理以及捕获,相比ASP.NET Web Form,ASP.NET MVC的处理方式有所不同,以往是通过注册Global.asax文件中的Application_Error事件进行全局异常捕获,现在MVC可以使用强大的过滤器进行自定义错误的处理。本文作为学习笔记,将ASP.NET MVC中,我已知的几种全局异常捕获及处理的思路进行整理和对比分析。

使用Global.asax的Application_Error事件进行全局异常处理

此方法对于Web Form和MVC来说都是通用的,在ASP.NET中,只要网站程序抛出未捕获的异常都会触发Application_Error事件。我们在事件中通过Server.GetLastError()方法获取Exception对象(可转化成HttpException对象,以获取相关的HTTP错误代码)。

使用此方法一定要把GlobalFilter全局过滤器中的HandleErrorAttribute注册取消掉,也可以将配置文件中的customErrors节点关闭,否则HTTP 500的错误将不会被Application_Error事件捕获。

还要注意一点,如果想在事件中跳转到自己定义的错误页面,那么在响应输出之前一定要记得调用 Server.ClearError()方法清除异常。否则会有下面两种情况,如果自定义错误关闭,会显示错误黄页(即详细异常信息页面),如果没关闭则会跳转到自定义错误定义的页面:

在Application_Error事件中处理全局异常

效果图如下:

全局异常跳转到正确的错误信息页面

小结:这种方法有非常好的兼容性,可以在Web Form和MVC中通用。另外一点是SEO优化十分友好,我们可以对HTTP错误码进行控制,毕竟customErrors是使用302跳转,是十分不利于SEO的。此外要注意在MVC中Server.Transfer不支持路由!

具体的操作方法和代码看这篇文章:ASP.NET MVC中注册Global.asax的Application_Error事件处理全局异常

使用HandleErrorAttribute特性捕获全局异常

ASP.NET MVC为异常处理提供了一个HandleErrorAttribute特性,该特性主要捕获及处理由操作方法引发的异常,一般在visual studio中新建的项目都是默认全局注册,通过GlobalFilter全局过滤器注册了此特性,所以整个ASP.NET MVC网站程序中所引发的异常默认都会被HandleError捕获到!

另外需要注意的是,HandleError特性是基于customErrors(自定义错误消息处理功能),所以只有在Web.config配置文件中设置customErrors元素的mode="On"或者或"RemoteOnly",HandleError特性才能有效,具体看源码中的这段判断:

// If custom errors are disabled, we need to let the normal ASP.NET exception handler
// execute so that the user can see useful debugging information.
if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled)
{
    return;
}

PS:本人使用的是vs2013新建的MVC 5项目

打开项目中的Global.asax文件,可以看到默认调用了FilterConfig类对HandleError特性进行全局注册:

默认全局注册了异常处理特性

FilterConfig.cs文件在App_Start下:

过滤器配置文件类

FilterConfig类代码如下:

using System.Web;
using System.Web.Mvc;

namespace asp.net_mvc_global_exception
{
    public class FilterConfig
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {            
            filters.Add(new HandleErrorAttribute());
        }
    }
}

如果上面的代码中我们不注册HandleErrorAttribute,那么此特性就会失效,但是我们依然可以设置customErrors元素搭配Web窗体进行自定义错误的处理,就和以往Web Form的处理方式一样,也算是另一种方式吧。

小结:对于HandleError特性的使用,我一般是用在B/S架构的企业系统中,有时候还会根据需求继承此特性以扩展功能,比如需要记录错误日志。另外此特性不对404错误进行任何处理,查看HandleErrorAttribute.cs文件源码,在源码中可看出对404做了额外处理:

有关此特性具体的可以看这篇文章:ASP.NET MVC 5 学习笔记:使用HandleErrorAttribute处理异常。文章中有代码样式和范例下载

继承IExceptionFilter接口扩展自定义异常处理功能

在ASP.NET MVC高级编程中是这样描述的:

异常过滤器用来处理操作或结果执行期间可能抛出的异常。参与异常处理的操作过滤器需要实现IExceptionFilter接口。ASP.NET MVC 框架只提供了一个异常过滤器:[HandleError]

说到IExceptionFilter接口,就要提到上面所介绍的HandleError特性,可以从源码中看到HandleErrorAttribute就是实现了IExceptionFilter接口和FilterAttribute特性:

但是HandleErrorAttribute作为默认提供的异常处理特性,有很多限制和不灵活的地方,比如不处理404,需要开启自定义错误,只能使用视图界面等。因此我们可以通过继承IExceptionFilter这个异常过滤接口,扩展和编写我们自己所需的处理流程。

继承IExceptionFilter接口,需要实现void OnException(ExceptionContext filterContext)方法,通过方法中的ExceptionContext类参数,我们可以极为灵活的编写各种异常处理流程,比如:

  1. 可以通过Exception属性获取异常对象和相关信息,保存错误日志或者判断异常类型来操作。
  2. 可以通过HttpContext属性来获取HTTP上下文类,从而操作HTTP状态码、跳转到相关URL页面、或者通过IsCustomErrorEnabled属性判断是否需要依赖自定义错误功能等等操作。

ExceptionContext类属性

小结:除非考虑项目中要兼容web form的问题,在MVC中我是十分喜欢用这种方式进行自定义异常处理。

关于此接口更多详情和注意事项可以查阅这篇文章:ASP.NET MVC实现IExceptionFilter接口编写自定义异常处理过滤器


结尾:对于本文所提及到全局异常处理思路,都是在MVC中比较常用到的,如有遗漏和错误,网友可以在下方评论留言,感谢留言的朋友,有交流就有进步^^。本文只提供一个思路和总结,具体的演示代码和详细步骤在文中都有提供链接。


作者:十有三

出处:https://shiyousan.com/post/635811085690315732

版权声明:本文采用知识共享许可协议:署名-相同方式共享 4.0 国际(CC BY-SA 4.0)。欢迎转载本文,转载请声明出处或保留此段声明。


  • 上一篇: ASP.NET MVC 5 学习笔记:使用HandleErrorAttribute处理异常
  • 下一篇: 解决Visual Studio快捷键Ctrl+Alt+L与QQ热键冲突

相关文章
  • 奇怪的问题:ASP.NET MVC submit提交表单传入的模型实体对象为null和空值
  • ASP.NET MVC移除URL后面自动加上的AspxAutoDetectCookieSupport=1
  • 如何禁用Visual Studio实时调试?
  • asp.net mvc 使用XmlWriter输出XML未调用Close方法造成错误
  • ASP.NET MVC UrlParameter.Optional字段用法和意思
  • ASP.NET MVC 表单提交多层子级实体集合数据到控制器中
发表评论
记住昵称

文章分类

.NET技术 122 数据库 24 Web前端 21 网站建设运维 33 操作系统与应用 67 程序猿日常 11 开发工具 11 其他随笔 12

文章标签

ASP.NET ASP.NET MVC C# CSS HTML IIS Javascript Linux MongoDB MySql SQL SQL Server Visual Studio Windows系统 版本控制系统 插件工具 道学 佛经 服务器 搞笑娱乐 好文分享 软件应用 生活知识 诗词 手机问题 随笔 网络知识 网站设计优化 网站维护 养生保健 异常处理 硬件设备 游戏攻略

热门文章

  • 解决IE11安装升级失败和在安装前需要更新的问题
  • 林蛋大与楚中天,朱肚皮与朱月坡
  • jquery ajax error函数和及其参数详细说明
  • 骑马与砍杀 无限箭枝/作弊修改箭枝数量/调整各种箭枝数量的方法
  • 在唯一密钥属性“fileExtension”设置为“.”时,无法添加类型为“mimeMap”的重复集合项

推荐文章

  • 解决"无法启动此程序,因为计算机中丢失cudart32_60.dll。尝试重新安装该程序以解决此问题。"
  • Visual Studio 2017 如何打开Model Browser(实体数据模型浏览器)
  • 此设备上的其他用户使用了此Microsoft帐户,无法在此处进行添加
  • Visual Studio 2013 社区版和速成版之间的区别
  • 解决vs2010添加项目后解决方案资源管理器中没有显示解决方案的问题

最新评论

  • 感谢脖主分享
  • 在“为click once清单签名”的右侧,可以创
  • 用的帝国cms,修改后无效啊。 缓存清理了,浏览
  • 我的需求是:分享出去是同一个网站,但是微信分享需要
  • 试了 的确 有效,只能用english的语言进行安

友情链接

  • Wil的博客
  • Passingwind的博客
  • 坤哥网
  • .NET开发者社区

知识共享许可协议 CC BY-SA 4.0本站作品采用知识共享许可协议:署名-相同方式共享 4.0 国际(CC BY-SA 4.0)。
闽ICP备15003702号