[Web API] 如何让 Web API 统一回传格式以及例外处理[转]
?
前言
當我們在開發 Web API 時,一般的情況下每個 API 回傳的數據型態或格式都不盡相同,如果你的項目從頭到尾都是由你一個人獨力完成,那也許還可以說聲「阿密陀佛」,但如果是有其他人需要和你共享你的 Api ,而回傳的數據格式又不一樣,相信是會增加使用者的困擾,也大大增加了程序的復雜度與維護上的難度。所以本篇也紀錄一下自己在實作上的經驗,一方面留個紀錄也希望幫助更多人,廢物不多說我們開始吧!
了解架構并實作
原本在找數據時找到這篇 使用Asp.NET MVC打造Web Api (16) – 統一輸入/出格式以及異常處理策略,不過發現里面的所用到的方法似乎是 For ASP.Net MVC,而非 Web API (不知道筆者這樣認知有沒有錯誤,如果有還麻煩前輩們指教),而本篇的思考模式跟這篇是一樣的,只是把它改成 Web API 能用的方法而已。
[]
按照上圖所示當使用者請求不同的 API 時,返回頁面之前會將數據重新打包后再傳回頁面給使用者,如此一來用戶所看到的數據格式就會是固定的。
1.所以首先我們需要先自定義一個 Model 來當作我們的包裝的容器,其類別的定義如下:
{ public HttpStatusCode Status { get; set; } public object Data { get; set; } public string ErrorMessage { get; set; } 2.相信寫過 ASP.NET MVC 的朋友一定會知道,一般我們會將一些在 Action 中固定的邏輯,利用 Filter 來套用到每一個 Action 上面,例如:Authorize。如果你對 Filter 不是很熟悉可以參考一下網絡上前輩所寫的文章:[VS2010] ASP.NET MVC with Action Filters。 所以這邊我們也需要使用同樣的技巧來重新打包我們回傳的數據格式,我們先新增一個 ApiResultAttribute.cs 的檔案,且繼承 System.Web.Http.Filters.ActionFilterAttribute,并且復寫OnActionExecuted 的方法,如下:?
{ { base.OnActionExecuted(actionExecutedContext); }3.而 OnActionExecuted 會在 Action 執行之后呼叫,也表示我們將資料送進這個方法里面,接著處理我們主要打包的程序邏輯,程序代碼如下:
{ base.OnActionExecuted(actionExecutedContext); ? ApiResultModel result = new ApiResultModel(); ? result.Status = actionExecutedContext.ActionContext.Response.StatusCode; result.Data = actionExecutedContext.ActionContext.Response.Content.ReadAsAsync<object>().Result; actionExecutedContext.Response = actionExecutedContext.Request.CreateResponse(result.Status, result); 4.而為了要讓所有的 Web API 都能套用我們自定義的 Filter,所以我們需要到 App_Start → WebApiConfig.cs→ Register 來注冊全局的 Web API Filter。(注意:若要注冊 Web API 的 Filter 需在 WebApiConfig.cs 中注冊,而非 FilterConfig.cs 中)?
config.Filters.Add(new ApiResultAttribute());5.重新建置之后我們再重新執行一次原先的 Web API 程序,就會看到回傳的格式已經變成我們自定義的格式了:
"Data": [ "Account": "taxi", "Name": "王大明", "AccountStatus": true { "Mark": "", "Telephone": "0922335111", }, "Account": "q121234567", "Name": "0000", "AccountStatus": true ], 例外處理?
前面我們已經將訊息打包成我們要的格式了,不過我們還沒確切地去處理有關例外的程序代碼,一般當程序發生錯誤產生例外時,我們當然也希望接收端能知道程序發生錯誤,進而顯示該顯示的訊息,而不是活生生地看著程序 Crash 或是停頓,這樣將帶給你的客戶不好的體驗,而在 ASP.NET MVC 中也有提供專門處理例外的 ExceptionFilterAttribute,所以接著來看看該如何打包我們的例外訊息吧。
1.新增一個 ApiErrorHandleAttribute.cs 并且繼承 System.Web.Http.Filters.ExceptionFilterAttribute,接著復寫 OnException 當例外發生時執行的方法,程序代碼如下:
{ { base.OnException(actionExecutedContext); }2.透過 OnException 的方法能讓我們捕捉當例外發生時要處理的事情,一般系統我們也會在這邊將發生錯誤的時間、登入的用戶以及錯誤的狀況記錄下來 (例如:系統事件、存入數據庫、寫入 .txt 檔 … 等),不過這邊不是我們討論的重點,我們先來看看該如何打包我們的例外訊息,程序代碼如下:
{ base.OnException(actionExecutedContext); // 取得發生例外時的錯誤訊息 var errorMessage = actionExecutedContext.Exception.Message; ? { ErrorMessage = errorMessage }; ? actionExecutedContext.Response = actionExecutedContext.Request .CreateResponse(result.Status, result); ??
3.而因為程序丟出例外后會先回到 OnActionExcuted 在進到例外的處理,所以我們稍微修改一下原本的 OnActionExcuted 這個方法,讓發生例外時就直接跳過不再這邊打包我們的訊息,程序代碼如下:
{ if (actionExecutedContext.Exception != null) return; base.OnActionExecuted(actionExecutedContext); ? ApiResultModel result = new ApiResultModel(); ? result.Status = actionExecutedContext.ActionContext.Response.StatusCode; result.Data = actionExecutedContext.ActionContext.Response.Content.ReadAsAsync<object>().Result; actionExecutedContext.Response = actionExecutedContext.Request.CreateResponse(result.Status, result); 3.接著我們一樣要將此自定義的 Filter 注冊到程序當中,所以一樣到 App_Start → WebApiConfig.cs → Register 來注冊我們的 Filter:?
config.Filters.Add(new ApiErrorHandleAttribute());4.重新建置后,當我們程序發生例外時也會依照我們的格式回傳給使用者:
"Status": 400, "ErrorMessage": "嘗試以零除。" 總結?
就這樣我們又成功解決了一個簡單的案例,不過這邊也需要提醒一下讀者,一般在處理例外這邊是不會直接將例外訊息回傳給用戶的,因為如果假設你今天丟出的例外有包含了一些比較敏感的信息,例如:數據庫名稱或數據表名稱…等等,這樣一來你的程序就間接的有了漏洞了,所以如果真的要用此程序代碼記得后面例外捕捉那邊還要在包裝一下。
原文地址:http://blog.csdn.net/for12/article/details/49685567
轉載于:https://www.cnblogs.com/jimcsharp/p/6085738.html
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的[Web API] 如何让 Web API 统一回传格式以及例外处理[转]的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用Nexus搭建Maven私服
- 下一篇: TimSort算法分析