欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

WebAPI接口设计:SwaggerUI文档 / 统一响应格式 / 统一异常处理 / 统一权限验证

程序员文章站 2022-05-11 14:41:28
为什么还要写这类文章?因为我看过网上很多讲解的都不够全面,而本文结合实际工作讲解了swaggerui文档,统一响应格式,异常处理,权限验证等常用模块,并提供一套完善的案例源代码,在实际工作中可直接参考使用。 一、先看看最终效果 这是最后生成的swagerui文档,大家可以直接访问这个地址体验: ht ......

为什么还要写这类文章?因为我看过网上很多讲解的都不够全面,而本文结合实际工作讲解了swaggerui文档,统一响应格式,异常处理,权限验证等常用模块,并提供一套完善的案例源代码,在实际工作中可直接参考使用。

一、先看看最终效果

这是最后生成的swagerui文档,大家可以直接访问这个地址体验:

(若无法访问,请公众号codel联系)

git源码地址:https://gitee.com/daimali/webapidemo (推荐直接看源码)

 

 文档效果图:

WebAPI接口设计:SwaggerUI文档 / 统一响应格式 / 统一异常处理 / 统一权限验证

响应的内容:

注意看红色部分,所有的响应内容都将自动封装成如下格式:由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文档文件

WebAPI接口设计:SwaggerUI文档 / 统一响应格式 / 统一异常处理 / 统一权限验证

WebAPI接口设计:SwaggerUI文档 / 统一响应格式 / 统一异常处理 / 统一权限验证

 

三、统一响应格式说明

通过 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统一封装:

WebAPI接口设计:SwaggerUI文档 / 统一响应格式 / 统一异常处理 / 统一权限验证
public class apiresultfilterattribute : actionfilterattribute
    {
        public override void onactionexecuted(httpactionexecutedcontext filtercontext)
        {
            base.onactionexecuted(filtercontext);

            if (filtercontext.actioncontext.response != null)
            {
                responseapi<object> result = new responseapi<object>();
                //权限验证 省略......
                var token = false;
                if (token)
                {
                    // 取得由 api 返回的状态代码
                    result.code = (int)httpstatuscode.unauthorized;
                    // 取得由 api 返回的资料
                    result.data = null;
                    result.msg = "invalid ticket value";
                }
                else
                {
                    // 取得由 api 返回的状态代码
                    result.code = (int)filtercontext.actioncontext.response.statuscode;
                    // 取得由 api 返回的资料
                    result.data = filtercontext.actioncontext.response.content.readasasync<object>().result;
                    result.msg = filtercontext.actioncontext.response.statuscode.tostring();
                }
                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实现:

WebAPI接口设计:SwaggerUI文档 / 统一响应格式 / 统一异常处理 / 统一权限验证
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

 

 

看源码

需要说的东西太多,直接看源码更方便:

接口预览地址:

(若无法访问,请公众号联系)

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的格式了

 

评论区已知问题(待解决,后续将持续更新demo,感兴趣的同学多多关注):

1. 解决swagger 文件上传问题   

 

 

相关资源获取或其他疑问可在公众号codel留言。