WebAPI接口設計:SwaggerUI文檔 / 統一響應格式 / 統一異常處理 / 統一權限驗證


為什么還要寫這類文章?因為我看過網上很多講解的都不夠全面,而本文結合實際工作講解了swaggerui文檔,統一響應格式,異常處理,權限驗證等常用模塊,並提供一套完善的案例源代碼,在實際工作中可直接參考使用。

一、先看看最終效果

這是最后生成的swagerui文檔,大家可以直接訪問這個地址體驗:

http://sapi.daimali.com/swagger/ui/index

(若無法訪問,請公眾號CodeL聯系)

git源碼地址:https://gitee.com/daimali/WebApiDemo (推薦直接看源碼)

 

 文檔效果圖:

響應的內容:

注意看紅色部分,所有的響應內容都將自動封裝成如下格式:由code,msg,data三部分組成

{
  "code": 200,
  "msg": "OK",
  "data": {
    "List": [
      {
        "OrderId": 1001,
        "UserName": "綠巨人",
        "OrderDate": "2018-11-18T09:39:36.0404502+08:00"
      },
      {
        "OrderId": 1002,
        "UserName": "鋼鐵俠",
        "OrderDate": "2018-11-17T09:39:36.0404502+08:00"
      }
    ],
    "total": 20
  }
}

 

實現以上API的整體思路是:

1. 使用SwaggerUI自動生成接口文檔、便於團隊協作,減少工作量

2. 通過ActionFilter實現權限控制與響應格式的統一封裝

3. 通過ExceptionFilter實現異常的統一處理

 

我覺得大部分人閱讀到這里就可以了,剩下的時間去看看源碼,需要用的時候邊用邊學就好了

 

二、接口文檔 - SwaggerUI注意點

1. swagger漢化,注意swagger_lang.js 屬性生成操作需要選擇"嵌入的資源"

2. 項目右鍵-屬性-生成:輸出項勾選XML文檔文件

 

三、統一響應格式說明

通過 ApiResultFilterAttribute 類實現響應參數的統一封裝:ApiResultFilterAttribute繼承自ActionFilterAttribute

這里封裝的響應格式由如下三部分組成: code:跟隨HttpCode,msg:返回的描述信息, data:接口返回的業務數據統一放在data中

{  

     "code": 200, 

     "msg": "OK", 

     "data": null

}
    /// <summary>
    /// 響應數據
    /// </summary>
    /// <typeparam name="T">自定義響應的內容</typeparam>
    public class ResponseApi<T>
    {
        /// <summary>
        /// 錯誤代碼
        /// </summary>
        public int code { get; set; }
        /// <summary>
        /// 錯誤信息
        /// </summary>
        public string msg { get; set; }
        /// <summary>
        /// 響應數據
        /// </summary>
        public T data { get; set; }

    }

通過actionfilter統一封裝:

public class ApiResultFilterAttribute : ActionFilterAttribute
    {
        /// <summary>
        /// 進入action之前做權限驗證
        /// </summary>
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            var token = true;
            //權限驗證省略
            if (token)
            {
                ResponseApi<object> result = new ResponseApi<object>();
                // 取得由 API 返回的狀態代碼
                result.code = (int)HttpStatusCode.Unauthorized;
                // 取得由 API 返回的資料
                result.data = null;
                result.msg = "invalid ticket value";

                HttpResponseMessage response = new HttpResponseMessage
                {
                    Content = new StringContent(JsonConvert.SerializeObject(result),
                       Encoding.GetEncoding("UTF-8"), "application/json")
                };
                //結果轉為自定義消息格式
                HttpResponseMessage httpResponseMessage = response;

                // 重新封裝回傳格式
                actionContext.Response = httpResponseMessage;
            }
        }
        /// <summary>
        /// 統一響應格式
        /// </summary>
        public override void OnActionExecuted(HttpActionExecutedContext filterContext)
        {
            base.OnActionExecuted(filterContext);

            if (filterContext.ActionContext.Response != null)
            {
                ResponseApi<object> result = new ResponseApi<object>();
                // 取得由 API 返回的狀態代碼
                result.code = (int)filterContext.ActionContext.Response.StatusCode;
                // 取得由 API 返回的資料
                result.data = filterContext.ActionContext.Response.Content.ReadAsAsync<object>().Result;
                HttpResponseMessage response = new HttpResponseMessage
                {
                    Content = new StringContent(JsonConvert.SerializeObject(result),
                       Encoding.GetEncoding("UTF-8"), "application/json")
                };
                //結果轉為自定義消息格式
                HttpResponseMessage httpResponseMessage = response;

                // 重新封裝回傳格式
                filterContext.Response = httpResponseMessage;

            }
        }
    }
ApiResultFilterAttribute.cs

 

 

四、自定義異常信息

針對於所有的異常信息,接口也會返回對應的code,msg,data的格式:

通過CustomException和CustomExceptionFilterAttribute實現:

public class CustomExceptionFilterAttribute : ExceptionFilterAttribute
    {
        /// <summary>
        /// 統一對調用異常信息進行處理,返回自定義的異常信息
        /// </summary>
        /// <param name="context">HTTP上下文對象</param>
        public override void OnException(HttpActionExecutedContext context)
        {
            //自定義異常的處理
            if (context.Exception is CustomException)
            {
                var exception = (CustomException)context.Exception;
                ResponseApi<object> result = new ResponseApi<object>()
                {
                    code = exception.GetErrorCode(),
                    msg = exception.Message
                };
                throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.OK)
                {
                    //封裝處理異常信息,返回指定JSON對象
                    Content = new StringContent(JsonConvert.SerializeObject(result),
                    Encoding.GetEncoding("UTF-8"), "application/json"),
                    ReasonPhrase = "InternalServerErrorException",
                });
            }
            else
            {
                ResponseApi<object> result = new ResponseApi<object>()
                {
                    code = -1,
                    msg = context.Exception.Message
                };
                throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.InternalServerError)
                {
                    //封裝處理異常信息,返回指定JSON對象
                    Content = new StringContent(JsonConvert.SerializeObject(result)),
                    ReasonPhrase = "InternalServerErrorException"
                });
            }
        }
    }
CustomExceptionFilterAttribute.cs

 

 

看源碼

需要說的東西太多,直接看源碼更方便:

接口預覽地址:http://sapi.daimali.com/swagger/ui/index

(若無法訪問,請公眾號聯系)

git源碼地址:https://gitee.com/daimali/WebApiDemo

 

繼續看詳細步驟:

1. 新建空ASP.NET MVC空應用程序,選擇WebApi

2. Nuget引用Swashbuckle.Core  (demo目前用的v5.6.0最新穩定版)

3. 將App_Start中的類復制到你的新項目中,然后更改命名空間為你自己項目

4. 按需調整SwaggerConfig.cs 配置

5. 將Scripts文件復制到你的項目中,同時設置 swagger_lang.js 文件 屬性- 生成操作為"嵌入的資源",按需調整 swagger_lang.js文件內容

6. 注意你的WebApiConfig中需要添加 ApiResultFilterAttributeCustomExceptionFilterAttribute

7. 項目右鍵-屬性-生成:輸出項勾選XML文檔文件 

此時,你新建的webapi控制器已經支持swagger,並且會統一封裝成code,msg,data的格式了

 

修正:

1. HttpGet 請求接收參數時需要加 [FromUri]

2. token驗證不應該放在OnActionExecuted中,應該在接口執行之前,比如:AuthorizeAttribute中,或者 ActionFilterAttribute里面的OnActionExecuting方法(源碼已調整為OnActionExecuting )

 

 

評論區已知問題(待解決,后續將持續更新Demo,感興趣的同學多多關注):

1. 解決swagger 文件上傳問題   

 

 

相關資源獲取或其他疑問可在公眾號CodeL留言。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM