去年很早的时候写过几篇关于ASP.NET MVC异常处理的方法和总结,后面遇到有网友留言,感觉在看过文章后虽然知道了多种全局异常处理的方案,但是在如何选择上出现了困惑,这里我就根据自己的一些项目经验来分析和说明下。
在ASP.NET MVC中,我所知的全局异常处理一共有三种方法:
- Global.asax的Application_Error事件
- ASP.NET MVC默认的HandleErrorAttribute特性
- 自己实现IExceptionFilter接口
在仔细的细分,上面的三种全局异常处理的方法要排除掉HandleErrorAttribute特性,也就是只剩下Global.asax的Application_Error事件和实现IExceptionFilter这个异常过滤器接口,因为HandleErrorAttribute特性本来就是通过实现IExceptionFilter接口的一个异常过滤器,是官方默认提供的异常处理机制,方便一些只需要简单处理的异常捕获。
现在看就只剩下两种方式,大体上看没有什么不同,反正都可以做全局自定义异常处理。但是Application_Error事件存在一个严重的不足,这点也是IExceptionFilter接口存在的必要:Application_Error事件无法针对Action和Controller级别的异常做较好的切入处理!
举个简单的例子,某个业务逻辑复杂的项目,在某个控制器中的Action操作,一旦引发了特定的异常,需要根据异常类型跳转到不同的错误页面。如果使用Application_Error事件就十分不好处理,首先在全局异常处理中,我一般是不做太复杂的业务逻辑处理,通常就是做下错误日志记录,返回一些简单的错误信息,跳转通用的HTTP 500错误页面、HTTP 404页面或者提示信息较为友好的错误页面。逻辑不能太过复杂,不然代码侵入性太高了,会导致整个Global.asax十分臃肿。
我在项目中做全局异常处理,最主要目的是作为最后一道防线,捕捉项目中未进行过处理的异常。只是如果遇到对异常捕捉没有什么特别要求的项目,我也是直接用Application_Error来实现统一化自定义异常处理,这种情况就十分合适了,也比较方便。
但是一旦项目业务逻辑复杂的,对异常捕获等级有要求的,只能使用IExceptionFilter自己实现特定的异常过滤器接口,毕竟IExceptionFilter接口对Action和Controller级别的异常都可以轻松的切入处理,减少业务逻辑代码中大量的try catch块。
这里再举个业务例子,在某个项目中有个订单控制器:OrderController,假设只有一个删除订单的操作DeleteResult,再假设订单的业务逻辑般是十分复杂的,需要考虑的情况很多,比如删除的时候要判断订单是否能删除(用户是否有权限,订单是否被冻结,完成的订单禁止删除等),删除订单后商品库存如何操作等七七八八的问题。
这种情况下,一般如果出现异常,可不是简单的跳转到一个HTT P500错误页面就可以解决的,很多情况下都要预先编写自定义错误Exception来处理,根据DeleteResult这个Action抛出的不同异常,跳转到指定的错误页面中,方便操作人员进行后续处理。比如订单是因为被冻结的,在错误页面中肯定要显示详细的冻结原因,如何解决冻结操作,负责人的联系方式等等,需要进行哪些步骤,这些都不可能用通用模板和几句简单的错误信息就可以说明的。其他的像是用户没有权限的,商品库存数据同步失败等情况,都要专门的错误页面,这样操作人员才有办法进行下一步。
最后小结下,其实主要还是需求!根据自己项目的需求来选择不同的异常处理方式:
- 在项目中,如果不需要做复杂的异常捕获,考虑到SEO的(搜索引擎优化的),或者需要与旧项目兼容的,我一般也是直接用Global.asax的Application_Error事件来做处理,实现统一化自定义异常处理。
- 一些小型的后台管理类型的项目,我直接用HandleErrorAttribute特性,一般类似企业后台的项目都不怎么需要做SEO,毕竟是内部自己使用。
- 需要复杂的异常捕获,我一般是通过实现IExceptionFilter接口来编写自定义异常处理过滤器,另外这种方式对SEO也十分友好,只要注意对应的HTTP代码操作。不过有个缺点就是只能捕获Action方法抛出的异常,所以可能需要和其他异常处理方式进行搭配互补。
另外关于这几种异常处理机制的优缺点,贴下我2年前写的相关文章地址:
- ASP.NET MVC实现IExceptionFilter接口编写自定义异常处理过滤器
- ASP.NET MVC全局异常处理和捕获的思路
- ASP.NET MVC 5 学习笔记:使用HandleErrorAttribute处理异常
其实优缺点大体上无外乎SEO,兼容性,复杂性,异常捕获范围,还有就是看需求!
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/99036.html