Abp中在新版本中,抛出的异常(比如:UserFriendlyException)通过AjaxResponse封装后返回的时候,HttpStatusCode默认指定成了500。
对于一些默认封装好的处理Http请求的组件,有一部分是不支持开发者去处理这个500以上的错误信息的,或者这个错误码对于一些前端开发来说很困惑。
因为一般500的错误都是服务器发生了异常,被动的抛出的一个错误,在很多客户端是不给用户展示的,所以一些HttpClient对500以上的错误就默认处理,提示发生服务器内部错误,在自己内部消化了这个错误导致开发人员不能自由的处理Http请求。
当然处理这个错误的最便捷方式,就是换一个Http Client不就可以了。
嗯,确实换一个就好了。
不过这里笔者本着研究学习的态度,还是找到了另一个方式处理这个问题,就是自定义HttpStatusCode。
在Abp中,处理错误请求是通过ExceptionFilter来处理的,如下图的两个方法就是需要我们改造的方法。
看下GetStatusCode的源码:
最后这个代码可以看到,ABP默认错误返回了500。
修改方法:
(1)添加一个CustomeException.cs,继承UserFriendlyException,添加一个属性HttpCode.
/// <summary> /// 自定义错误状态吗 /// </summary> public class CustomeException : UserFriendlyException { public CustomeException(int code, string message, string details) : this((int)HttpStatusCode.BadRequest, code, message, details) { } public CustomeException(HttpStatusCode httpCode, int code, string message, string details) : this((int)httpCode, code, message, details) { } public CustomeException(int httpCode, int code, string message, string details) : base(code, message, details) { HttpCode = httpCode; } /// <summary> /// http 状态码 /// </summary> public int HttpCode { get; set; } }
(2)添加CustomeApiExceptionFilterAttribute,继承AbpApiExceptionFilterAttribute,然后重写GetStatusCode方法。
public class CustomeApiExceptionFilterAttribute : AbpApiExceptionFilterAttribute, ITransientDependency { public CustomeApiExceptionFilterAttribute(IAbpWebApiConfiguration configuration) : base(configuration) { } protected override HttpStatusCode GetStatusCode(HttpActionExecutedContext context) { var customException = (context.Exception as CustomeException); if (customException != null) { return (HttpStatusCode)customException.HttpCode; } else { return base.GetStatusCode(context); } } public void UseThis() { var filters = Configuration.HttpConfiguration.Filters; var filterInfo = filters.FirstOrDefault(h => h.Instance is AbpApiExceptionFilterAttribute); if (filterInfo != null) { filters.Remove(filterInfo.Instance); } filters.Add(this); } }
(3)替换原来的ExceptionFilter。在WebApiModule中初始化方法中调用UseThis方法。
最终的代码目录:
上面的代码简单,就不写注释了。
以上三个步骤之后,在代码中抛出CustomeException就可以自定义httpStatusCode了。