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

一、先看看最终效果

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

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

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

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

 文档效果图:

响应的内容:

注意看红色部分,所有的响应内容都将自动封装成如下格式:由code,msg,data三部分组成

  1. {
  2. "code": ,
  3. "msg": "OK",
  4. "data": {
  5. "List": [
  6. {
  7. "OrderId": ,
  8. "UserName": "绿巨人",
  9. "OrderDate": "2018-11-18T09:39:36.0404502+08:00"
  10. },
  11. {
  12. "OrderId": ,
  13. "UserName": "钢铁侠",
  14. "OrderDate": "2018-11-17T09:39:36.0404502+08:00"
  15. }
  16. ],
  17. "total":
  18. }
  19. }

实现以上API的整体思路是:

1. 使用SwaggerUI自动生成接口文档、便于团队协作,减少工作量

2. 通过ActionFilter实现权限控制与响应格式的统一封装

3. 通过ExceptionFilter实现异常的统一处理

我觉得大部分人阅读到这里就可以了,剩下的时间去看看源码,需要用的时候边用边学就好了

二、接口文档 - SwaggerUI注意点

1. swagger汉化,注意swagger_lang.js 属性生成操作需要选择"嵌入的资源"

2. 项目右键-属性-生成:输出项勾选XML文档文件

三、统一响应格式说明

通过 ApiResultFilterAttribute 类实现响应参数的统一封装:ApiResultFilterAttribute继承自ActionFilterAttribute

这里封装的响应格式由如下三部分组成: code:跟随HttpCode,msg:返回的描述信息, data:接口返回的业务数据统一放在data中

  1. {
  2.  
  3. "code": ,
  4.  
  5. "msg": "OK",
  6.  
  7. "data": null
  8.  
  9. }
  1. /// <summary>
  2. /// 响应数据
  3. /// </summary>
  4. /// <typeparam name="T">自定义响应的内容</typeparam>
  5. public class ResponseApi<T>
  6. {
  7. /// <summary>
  8. /// 错误代码
  9. /// </summary>
  10. public int code { get; set; }
  11. /// <summary>
  12. /// 错误信息
  13. /// </summary>
  14. public string msg { get; set; }
  15. /// <summary>
  16. /// 响应数据
  17. /// </summary>
  18. public T data { get; set; }
  19.  
  20. }

通过actionfilter统一封装:

  1. public class ApiResultFilterAttribute : ActionFilterAttribute
  2. {
  3. /// <summary>
  4. /// 进入action之前做权限验证
  5. /// </summary>
  6. public override void OnActionExecuting(HttpActionContext actionContext)
  7. {
  8. var token = true;
  9. //权限验证省略
  10. if (token)
  11. {
  12. ResponseApi<object> result = new ResponseApi<object>();
  13. // 取得由 API 返回的状态代码
  14. result.code = (int)HttpStatusCode.Unauthorized;
  15. // 取得由 API 返回的资料
  16. result.data = null;
  17. result.msg = "invalid ticket value";
  18.  
  19. HttpResponseMessage response = new HttpResponseMessage
  20. {
  21. Content = new StringContent(JsonConvert.SerializeObject(result),
  22. Encoding.GetEncoding("UTF-8"), "application/json")
  23. };
  24. //结果转为自定义消息格式
  25. HttpResponseMessage httpResponseMessage = response;
  26.  
  27. // 重新封装回传格式
  28. actionContext.Response = httpResponseMessage;
  29. }
  30. }
  31. /// <summary>
  32. /// 统一响应格式
  33. /// </summary>
  34. public override void OnActionExecuted(HttpActionExecutedContext filterContext)
  35. {
  36. base.OnActionExecuted(filterContext);
  37.  
  38. if (filterContext.ActionContext.Response != null)
  39. {
  40. ResponseApi<object> result = new ResponseApi<object>();
  41. // 取得由 API 返回的状态代码
  42. result.code = (int)filterContext.ActionContext.Response.StatusCode;
  43. // 取得由 API 返回的资料
  44. result.data = filterContext.ActionContext.Response.Content.ReadAsAsync<object>().Result;
  45. HttpResponseMessage response = new HttpResponseMessage
  46. {
  47. Content = new StringContent(JsonConvert.SerializeObject(result),
  48. Encoding.GetEncoding("UTF-8"), "application/json")
  49. };
  50. //结果转为自定义消息格式
  51. HttpResponseMessage httpResponseMessage = response;
  52.  
  53. // 重新封装回传格式
  54. filterContext.Response = httpResponseMessage;
  55.  
  56. }
  57. }
  58. }

ApiResultFilterAttribute.cs

四、自定义异常信息

针对于所有的异常信息,接口也会返回对应的code,msg,data的格式:

通过CustomException和CustomExceptionFilterAttribute实现:

  1. public class CustomExceptionFilterAttribute : ExceptionFilterAttribute
  2. {
  3. /// <summary>
  4. /// 统一对调用异常信息进行处理,返回自定义的异常信息
  5. /// </summary>
  6. /// <param name="context">HTTP上下文对象</param>
  7. public override void OnException(HttpActionExecutedContext context)
  8. {
  9. //自定义异常的处理
  10. if (context.Exception is CustomException)
  11. {
  12. var exception = (CustomException)context.Exception;
  13. ResponseApi<object> result = new ResponseApi<object>()
  14. {
  15. code = exception.GetErrorCode(),
  16. msg = exception.Message
  17. };
  18. throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.OK)
  19. {
  20. //封装处理异常信息,返回指定JSON对象
  21. Content = new StringContent(JsonConvert.SerializeObject(result),
  22. Encoding.GetEncoding("UTF-8"), "application/json"),
  23. ReasonPhrase = "InternalServerErrorException",
  24. });
  25. }
  26. else
  27. {
  28. ResponseApi<object> result = new ResponseApi<object>()
  29. {
  30. code = -,
  31. msg = context.Exception.Message
  32. };
  33. throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.InternalServerError)
  34. {
  35. //封装处理异常信息,返回指定JSON对象
  36. Content = new StringContent(JsonConvert.SerializeObject(result)),
  37. ReasonPhrase = "InternalServerErrorException"
  38. });
  39. }
  40. }
  41. }

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留言。

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

  1. 服务器文档下载zip格式 SQL Server SQL分页查询 C#过滤html标签 EF 延时加载与死锁 在JS方法中返回多个值的三种方法(转载) IEnumerable,ICollection,IList接口问题 不吹不擂,你想要的Python面试都在这里了【315+道题】 基于mvc三层架构和ajax技术实现最简单的文件上传 事件管理

    服务器文档下载zip格式   刚好这次项目中遇到了这个东西,就来弄一下,挺简单的,但是前台调用的时候弄错了,浪费了大半天的时间,本人也是菜鸟一枚.开始吧.(MVC的) @using Rattan.Co ...

  2. 【奇淫技巧】API接口字段table文档转代码工具

    今天做一个视频接口对接,发现对方提供的文档没有json格式,无法自动生成请求和响应对象 json自动生成C#类的工具 http://tool.sufeinet.com/Creater/JsonClas ...

  3. [转]支付宝接口程序、文档及解读(ASP.NET)

    本文转自:http://www.cnblogs.com/blodfox777/archive/2009/11/03/1595223.html 最近需要为网站加入支付宝的充值接口,而目前关于支付宝接口开 ...

  4. <<海闻电子发票接口 ESB 封装文档>>

    <<海闻电子发票接口 ESB 封装文档>> 章节目录结构: 发票验证接口 发票开具接口 ESB请求地址: 发票验证接口: http://10.15.22.120:8866/42 ...

  5. 支付宝接口程序、文档及解读(ASP.NET)

    最近需要为网站加入支付宝的充值接口,而目前关于支付宝接口开发的资料比较杂乱,这里就我此次开发所用到的资料进行汇总整理,希望能够帮助需要的朋友. 开发步骤: 1. 确定签约类型 支付宝的接口有多种类型, ...

  6. 数字麦克风PDM转PCM与STM32 I2S接口应用----重要文档列表

    数字麦克风PDM脉冲到PCM信号需要一个二次采样,ST 提过了PDM2PCM的软件包,可以完成上面的工作.软件包源码没有开源,使用手册也简洁的让人抓狂,我觉得可能是因为ST更高级的MCU直接带了硬解码 ...

  7. Anakia 转换xml文档为其他格式

    一.简介 Anakia 使用JDOM 和Velocity将XML文档转换为特定格式的文档 二.解析xml文档方法 1.DOM java jdk,xml-api.jar 需要加载整个xml文档来构建层次 ...

  8. WebApi生成在线API文档--Swagger

    1.前言 1.1 SwaggerUI SwaggerUI 是一个简单的Restful API 测试和文档工具.简单.漂亮.易用(官方demo).通过读取JSON 配置显示API. 项目本身仅仅也只依赖 ...

  9. webAPI 自动生成帮助文档

    之前在项目中有用到webapi对外提供接口,发现在项目中有根据webapi的方法和注释自动生成帮助文档,还可以测试webapi方法,功能很是强大,现拿出来与大家分享一下. 先看一下生成的webapi文 ...

随机推荐

  1. mysql数据库单表只有一个主键自增id字段,ibatis实现id自增

    mysql数据库单表只有一个主键自增id字段,ibatis实现id自增 <insert id="autoid">        insert into user_id ...

  2. MFC控件编程之组合框跟列表框

    MFC控件编程之组合框跟列表框 一丶简介 如果要使用组合框跟列表框.那么就要知道.组合框列表框是最核心的东西就是索引. 索引是从0开始的. 二丶组合框列表框常用的方法 AddString(字符串) 添 ...

  3. Win32之隐藏DLL隐藏模块技术

    Win32之隐藏DLL隐藏模块技术 这一讲涉及到windows底层技术.跟汇编内容. 我们才可以实现模块隐藏(也称为DLL隐藏) 一丶API反汇编勾引兴趣 我们都用过Windows的进程跟线程API  ...

  4. 动态规划法(十)最长公共子序列(LCS)问题

    问题介绍   给定一个序列\(X=<x_1,x_2,....,x_m>\),另一个序列\(Z=<z_1,z_2,....,z_k>\)满足如下条件时称为X的子序列:存在一个严格 ...

  5. Python GUI

    1.flexx Flexx 是一个纯Python工具包,用来创建图形化界面应用程序.其使用 Web 技术进行界面的渲染.你可以用Flexx来创建桌面应用,同时也可以导出一个应用到独立的 HTML 文档 ...

  6. php常用函数搜集

    搜集了几个php常用函数方法....相信项目中肯定会用到吧... <?php /** * @param $arr * @param $key_name * @return array * 将数据 ...

  7. PHP中获取当前页面的URL信息

    <? //获取当前的域名: echo $_SERVER['SERVER_NAME']; //获取来源网址,即点击来到本页的上页网址 echo $_SERVER["HTTP_REFERE ...

  8. 10.QT-定时器

    QObject定时器 需要头文件#include <QTimerEvent>  需要函数 int QObject::startTimer(int interval); //启动定时器,并设 ...

  9. js实现ctrl+v上传图片

    描述:实现类似QQ截图删上传图片的功能 a.需要的js插件 paste.image.js 地址:https://github.com/iyangyuan/pasteimg b.paste.image. ...

  10. js 面向对象 ES5 AND ES6

    1. ES5实现 父类: // 职员类 function Employees(id,name,salary) { // 属性 this.id = id; this.name = name; this. ...