Web API--自定义异常结果的处理
1、常規的異常處理
統一的異常處理,把正確的信息返回給調用者很重要,可以讓接口開發人員或者用戶,了解具體的原因所在,這樣可以得到有效的錯誤處理。
參考微信API的處理,微信API,對于調用都有一個錯誤信息返回,不會直接裸露未經處理的異常,因此它們都是經過了一定的攔截處理,然后把錯誤信息包裝提供給接口調用方的。如下是微信的一些接口處理錯誤。
錯誤時微信會返回錯誤碼等信息,JSON數據包示例如下(該示例為AppID無效錯誤):{"errcode":40013,"errmsg":"invalid appid"}我們根據自己的需要,定義了一個統一的錯誤信息實體類,如下所示。
/// <summary>/// 接口返回的錯誤信息/// </summary>public class BaseResultJson{/// <summary>/// 錯誤代碼/// </summary>public int errcode { get; set; }/// <summary>/// 如果不成功,返回的錯誤信息/// </summary>public string errmsg { get; set; }/// <summary>/// 是否成功/// </summary>public bool success { get; set; }}這樣我們就可以把攔截到的錯誤信息,轉換為這樣一個方便使用的實體類信息了。
攔截Web API的調用異常,一般可以結合Try Catch的方法,以及異常攔截器進行處理,如下是主動拋出的一些異常信息處理。
//如果沒有通過,則拋出異常,由異常過濾器統一處理if (!result.success){throw new MyApiException(result.errmsg, result.errcode);}其中MyApiException是自定義的一個異常信息,用來承載自定義錯誤信息的異常類。
異常攔截器,我們在Web API里面可以通過Attribute這種標簽特性進行處理,如下是我在Web API的基類里面定義了一個異常處理器。
/// <summary>/// 所有接口基類/// </summary>[ExceptionHandling]public class BaseApiController : ApiController這個特性對象的定義,它的代碼如下所示。
/// <summary>/// API自定義錯誤過濾器屬性/// </summary>public class ExceptionHandlingAttribute : ExceptionFilterAttribute{/// <summary>/// 統一對調用異常信息進行處理,返回自定義的異常信息/// </summary>/// <param name="context">HTTP上下文對象</param>public override void OnException(HttpActionExecutedContext context){//自定義異常的處理MyApiException ex = context.Exception as MyApiException;if (ex != null){ throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.InternalServerError){//封裝處理異常信息,返回指定JSON對象Content = new StringContent(new BaseResultJson(ex.Message, false, ex.errcode).ToJson()),ReasonPhrase = "Exception"});}//記錄關鍵的異常信息Debug.WriteLine(context.Exception);//常規異常的處理string msg = string.IsNullOrEmpty(context.Exception.Message) ? "接口出現了錯誤,請重試或者聯系管理員" : context.Exception.Message;throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.InternalServerError){Content = new StringContent(msg),ReasonPhrase = "Critical Exception"});}}根據這些代碼,我們就可以實現對調用異常的統一封裝處理,讓它給我們返回統一的對象信息了,如下是其中一個調用異常,轉換為自定義異常信息后的結果輸出。
{"errcode":404,"errmsg":"請求的資源不支持 http 方法“POST”。","success":false}這樣我們在處理Web API的返回結果的時候,可以先處理它的異常信息,具體的處理代碼如下所示。
HttpHelper helper = new HttpHelper();helper.ContentType = "application/json";string content = helper.GetHtml(url, postData, true);VerifyErrorCode(content);T result = JsonConvert.DeserializeObject<T>(content);return result;我們在上面紅色部分的代碼就是先處理異常定義信息,如果有這些異常,我們可以在界面中進行異常處理顯示了。
例如,如果自定義異常存在,我們轉換后,把對應的信息顯示出來,重新拋出異常即可。
BaseResultJson errorResult = JsonConvert.DeserializeObject<BaseResultJson>(content);//非成功操作才記錄異常,因為有些操作是返回正常的結果({"errcode": 0, "errmsg": "ok"})if (errorResult != null && !errorResult.success){string error = string.Format("請求發生錯誤!錯誤代碼:{0},說明:{1}", (int)errorResult.errcode, errorResult.errmsg);LogTextHelper.Error(errorResult.ToJson());throw new Exception(error);//拋出錯誤}2、地址接口異常處理
對于常規的異常,我們通過上面的處理方式,就可以很好進行攔截并處理了,如果接口異常是全局性的,如訪問地址簿正確,或者參數多了幾個信息,那么調用的接口就不是有效的地址,這樣的話,返回的信息就不會被上面的攔截器進行處理了。
如我們給一個無效的API調用路徑,在瀏覽器中獲得下面錯誤結果。
上面結果就無法被我們的常規異常攔截器所捕獲,因此不會輸出經過封裝好的異常信息。
如果需要攔截,我們需要增加自己的消息代理處理,用來捕獲這些特殊的異常信息。
public static class WebApiConfig{public static void Register(HttpConfiguration config){..............config.MessageHandlers.Add(new CustomErrorMessageDelegatingHandler());上面紅色部分就是我們自己添加的消息代理處理類,用來處理一些特殊的異常信息,如下代碼所示。
/// <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(new BaseResultJson(error.Message, false, 404).ToJson()),ReasonPhrase = "Exception"});}else{return response;}});}}經過了上面的處理后,我們進一步測試一下不存在的地址的異常處理結果,可以看到輸出的內容是經過了自定義對象的轉換了。
常規的調用,如果接口不對應,那么錯誤也是類似下面的消息
{"errcode":404,"errmsg":"找不到與請求 URI“http://localhost:9001/api/SystemType/Delete?signature=72f8d706c79dc14d70fc3f080d4706748d754021×tamp=1443194061&nonce=0.650359861855563&appid=website_9A39C2A8&token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIxIiwiaWF0IjoxNDQzMTk0MDM4LCJqdGkiOiI1YmEyYmE5Ni0yZTA4LTQ1ZTgtYTAwNy01MmY3OTkzYTg2NzEiLCJuYW1lIjoiYWRtaW4iLCJjaGFubmVsIjoiMCIsInNoYXJlZGtleSI6IjEyMzRhYmNkIn0.RRXQmmSCJzDK5Or6rmBL5wjd-YIJoEQFc0pOzqhR6IU”匹配的 HTTP 資源。","success":false}有了這些信息,我們就可以統一我們的調用規則,并進行異常記錄和顯示了,非常方便。
http://www.cnblogs.com/wuhuacong/p/4843422.html
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的Web API--自定义异常结果的处理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 中间人(说一说中间人的简介)
- 下一篇: 马鞍山一县干部公示(马鞍山干部在线学习)