Web API系列(三)统一异常处理
前面講了webapi的安全驗證和參數安全,不清楚的朋友,可以看看前面的文章,《Web API系列(二)接口安全和參數校驗》,本文主要介紹Web API異常結果的處理。作為內部或者是對外提供的統一webapi 接口,統一的異常處理,把正確的信息返回給調用者很重要。這樣可以讓接口開發人員,了解具體的原因所在,這樣可以得到有效的錯誤處理。
需要注意的是,webapi異常的狀態碼,盡量不要和業務狀態碼混淆。可以分為兩個不同的字段,或者是狀態碼的規則不同。相關返回數據的格式,可以參考,前面的文章。
1、常規程序異常處理
常規的程序異常,指的是webapi 接口程序在執行的時候出現的各種異常情況,可以使用異常篩選器捕獲所有異常。
1.?API自定義錯誤過濾器屬性:ApiExceptionAttribute
/// <summary>/// API自定義錯誤過濾器屬性/// </summary>public class ApiExceptionHandlingAttribute : ExceptionFilterAttribute{/// <summary>/// 統一對調用異常信息進行處理,返回自定義的異常信息/// </summary>/// <param name="context">HTTP上下文對象</param>public override void OnException(HttpActionExecutedContext context){//自定義異常的處理if (context.Exception is NotImplementedException){throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotImplemented) {//封裝處理異常信息,返回指定JSON對象Content = new StringContent(JsonHelper.ToJson(new ErrorModel((int)HttpStatusCode.NotImplemented, 0, ex.Message)), Encoding.UTF8, "application/json"),ReasonPhrase = "NotImplementedException"});}else if (context.Exception is TimeoutException){throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.RequestTimeout){//封裝處理異常信息,返回指定JSON對象Content = new StringContent(JsonHelper.ToJson(new ErrorModel((int)HttpStatusCode.RequestTimeout, 0, ex.Message)), Encoding.UTF8, "application/json"),ReasonPhrase = "TimeoutException"});}//.....這里可以根據項目需要返回到客戶端特定的狀態碼。如果找不到相應的異常,統一返回服務端錯誤500else{throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.InternalServerError){//封裝處理異常信息,返回指定JSON對象Content = new StringContent(JsonHelper.ToJson(new ErrorModel((int)HttpStatusCode.InternalServerError, 0, ex.Message)), Encoding.UTF8, "application/json"),ReasonPhrase = "InternalServerErrorException"});}//base.OnException(context);//記錄關鍵的異常信息//Debug.WriteLine(context.Exception); }}?
2.?定義好了錯誤過濾器,根據實際情況,在不同級別使用統一的異常處理機制。比如,接口action級別,控制器Controller級別或者是全局。
我們目前的使用的是全局進行異常過濾。在ApiBase 增加異常過濾。
[ApiAuth][ApiExceptionHandling]public class ApiBase : ApiController2、地址接口異常處理
對于常規的異常,我們通過上面的處理方式,就可以很好進行攔截并處理了,如果接口異常是全局性的,如訪問地不正確,或者調用的接口就不是有效的地址,這樣的話,返回的信息就不會被上面的攔截器進行處理了。
如我們給一個無效的API調用路徑,在瀏覽器中獲得下面錯誤結果。
由于上面結果就無法被我們的常規異常攔截器所捕獲,因此不會輸出經過封裝好的異常信息。
所以如果需要攔截,我們需要增加自己的消息代理處理,用來捕獲這些特殊的異常信息。
/// <summary>/// API自定義錯誤消息處理委托類。/// 用于處理訪問不到對應API地址的情況,對錯誤進行自定義操作。/// </summary>public class CustomErrorMessageDelegatingHandler : DelegatingHandler{protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken){return base.SendAsync(request, cancellationToken).ContinueWith<HttpResponseMessage>((responseToCompleteTask) =>{HttpResponseMessage response = responseToCompleteTask.Result;HttpError error = null;if (response.TryGetContentValue<HttpError>(out error)){//添加自定義錯誤處理//error.Message = "Your Customized Error Message"; }if (error != null){//獲取拋出自定義異常,有攔截器統一解析throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound){//封裝處理異常信息,返回指定JSON對象Content = new StringContent(JsonHelper.ToJson(new ErrorModel(404, 0, error.Message)), Encoding.UTF8, "application/json"),ReasonPhrase = "Exception"});}else{return response;}});}}同時,在WebApiConfig中,注冊上相關處理
public static class WebApiConfig{public static void Register(HttpConfiguration config){..............config.MessageHandlers.Add(new CustomErrorMessageDelegatingHandler());有了以上這兩種異常處理,我們就可以統一我們的調用規則,并進行異常記錄和顯示了,非常方便。
3、總結
首先,以上這兩種異常處理,我們就可以統一我們的調用規則,但是對于WebApi里面異常的處理機制,可能還不夠深入,但對于一般項目的異常處理基本夠用。其他朋友,如果還有什么更好的方案,還望不吝賜教,感謝感謝!
其次,我們目前使用的異常處理,參考于http://www.cnblogs.com/wuhuacong/p/4843422.html。
?
總結
以上是生活随笔為你收集整理的Web API系列(三)统一异常处理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [LeetCode] Find All
- 下一篇: linux下解压大于4G文件提示erro