设为首页 加入收藏

TOP

ABP Changing Httpcode status(一)
2019-09-17 16:51:33 】 浏览:33
Tags:ABP Changing Httpcode status

  小弟初来乍到,分享一些工作学习中遇到的问题和解决方式,如有不准确或是有错误的地方,希望不吝赐教,谢过了。  --Dogtwo

 

起因:
ABP 中异常处理的思路是很清晰的。一共五种类型的异常类。

AbpInitializationException用于封装ABP初始化过程中出现的异常,只要抛出AbpInitializationException异常就可以,无须做额外处理。这类异常往往是需要维护人员介入分析的。

其他四个异常都在AbpController中被集中处理,处理分为两步:一,通过EventBus触发异常事件,相应的异常处理函数则处理异常。二,针对AbpValidationException,UserFriendlyException和AbpAuthorizationException异常,Abp会将异常信息转换为ErrorInfo,并以view或Json的形式返回给客户端。
(以上内容摘自 HK Zhand大大的博客

我们应使用UserFriendlyException来包装我们自定义的异常,但UserFriendlyException抛出的异常存在一个问题:无法指定HttpStatus code,这样前端收到的response中HttpStatus code均为500。对一部分前端语言或框架来说,这个状态码难以处理或不便于处理,因为约定5xx指示服务器异常,不应再由前端进行Handle。

所以,我们希望更改Response中的HttpStatus code。

思路很简单,我们利用filter去拦截异常,判断其类型,若为我们自定义的异常则更改HttpStatus code。

Filter部分代码

 1 public class MyExceptionFilter : IExceptionFilter
 2 {
 3     public ILogger Logger { get; set; }
 4 
 5     public MyExceptionFilter()
 6     {
 7         Logger = NullLogger.Instance;
 8     }
 9 
10     public void OnException(ExceptionContext context)
11     {
12         if (!(context.Exception is MyException))
13         {
14             return;
15         }
16 
17         HandleAndWrapException(context);
18     }
19 
20     private void HandleAndWrapException(ExceptionContext context)
21     {
22         context.HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
23 
24         var myException = (MyException)context.Exception;
25 
26         context.Result = new ObjectResult(
27           new AjaxResponse(
28             new ErrorInfo(myException.ErrorCode, myException.Message)
29         )    
30      );
31 
32         LogHelper.LogException(Logger, context.Exception);
33 
34         context.Exception = null; //Handled!
35     }
36 }            

然后再StartUp文件中添加filter

1 services.Configure(mvcOptions =>
2 {
3     mvcOptions.Filters.AddService(typeof(MyExceptionFilter ));
4 });

 

运行发现,filter并不能catch住我们抛出的异常,甚至OnException方法体都没进入。
原来,ABP本身实现了几个filter,包括Authorization Filter, Audit Action Filter, Validation Action Filter, Unit of Work Action Filter, Exception Filter和Result Filter.
造成我们的自定义filter无法正常执行的原因就是Exception Filter.

ABP官方文档介绍为:
AbpExceptionFilter is used to handle exceptions thrown from controller actions. It handles and logs exceptions and returns a wrapped response to the client.

This only handles object results, and not view results. Actions returning any object, JsonResult or ObjectResult will be handled. Actions are not handled if they return a view or any other result type implementing IActionsResult. It is recommend that you use the built-in UseExceptionHandler extension method defined in the Microsoft.AspNetCore.Diagnostics package to handle view exceptions.
Exception handling and logging behaviour can be changed using the WrapResult and DontWrapResult attributes for methods and classes.

除此之外, ABPExceptionFilter还会触发AbpHandledExceptionData eventbus event.且,经由ABPExceptionFilter处理之后,会将异常信息转换为ErrorInfo,并以view或Json的形式返回给客户端。所以当response通过ABPExceptionFilter之后便不再包含Exception了,自然我们的Filter捕捉不到了。

由此,想到两个解决方法
一 经由Event bus再次将异常抛出(很明显,如果是为了解决本问题的话,逻辑不通,很差的解决方式。已经被catch的异常再抛出来被自定义的filter去处理,七擒孟获)
但为了熟悉这部分的代码逻辑还是做了一下实现。

 1 public class MyExceptionHandler : IEventHandler, ITransientDependency
 2 {
 3     public ILogger Logger { get; set; }
 4 
 5     public MyExceptionHandler()
 6     {
 7         Logger = NullLogger.Instance;
 8     }
 9 
10     public void HandleEvent(AbpHandledExceptionData eventData)
11     {
12         Logger.
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇轻量级Config文件AppSettings节点.. 下一篇Docker学习笔记-磁盘挂载运行.net..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目