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了。