WebAPI接口设计:SwaggerUI文档 / 统一响应格式 / 统一异常处理 / 统一权限验证
为什么还要写这类文章?因为我看过网上很多讲解的都不够全面,而本文结合实际工作讲解了swaggerui文档,统一响应格式,异常处理,权限验证等常用模块,并提供一套完善的案例源代码,在实际工作中可直接参考使用。
一、先看看最终效果
这是最后生成的swagerui文档,大家可以直接访问这个地址体验:
http://sapi.daimali.com/swagger/ui/index
(若无法访问,请公众号CodeL联系)
git源码地址:https://gitee.com/daimali/WebApiDemo (推荐直接看源码)
文档效果图:
响应的内容:
注意看红色部分,所有的响应内容都将自动封装成如下格式:由code,msg,data三部分组成
{
"code": ,
"msg": "OK",
"data": {
"List": [
{
"OrderId": ,
"UserName": "绿巨人",
"OrderDate": "2018-11-18T09:39:36.0404502+08:00"
},
{
"OrderId": ,
"UserName": "钢铁侠",
"OrderDate": "2018-11-17T09:39:36.0404502+08:00"
}
],
"total":
}
}
实现以上API的整体思路是:
1. 使用SwaggerUI自动生成接口文档、便于团队协作,减少工作量
2. 通过ActionFilter实现权限控制与响应格式的统一封装
3. 通过ExceptionFilter实现异常的统一处理
我觉得大部分人阅读到这里就可以了,剩下的时间去看看源码,需要用的时候边用边学就好了
二、接口文档 - SwaggerUI注意点
1. swagger汉化,注意swagger_lang.js 属性生成操作需要选择"嵌入的资源"
2. 项目右键-属性-生成:输出项勾选XML文档文件
三、统一响应格式说明
通过 ApiResultFilterAttribute 类实现响应参数的统一封装:ApiResultFilterAttribute继承自ActionFilterAttribute
这里封装的响应格式由如下三部分组成: code:跟随HttpCode,msg:返回的描述信息, data:接口返回的业务数据统一放在data中
{ "code": , "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 = -,
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中需要添加 ApiResultFilterAttribute 和 CustomExceptionFilterAttribute
7. 项目右键-属性-生成:输出项勾选XML文档文件
此时,你新建的webapi控制器已经支持swagger,并且会统一封装成code,msg,data的格式了
修正:
1. HttpGet 请求接收参数时需要加 [FromUri]
2. token验证不应该放在OnActionExecuted中,应该在接口执行之前,比如:AuthorizeAttribute中,或者 ActionFilterAttribute里面的OnActionExecuting方法(源码已调整为OnActionExecuting )
评论区已知问题(待解决,后续将持续更新Demo,感兴趣的同学多多关注):
1. 解决swagger 文件上传问题
相关资源获取或其他疑问可在公众号CodeL留言。
WebAPI接口设计:SwaggerUI文档 / 统一响应格式 / 统一异常处理 / 统一权限验证的更多相关文章
- 服务器文档下载zip格式 SQL Server SQL分页查询 C#过滤html标签 EF 延时加载与死锁 在JS方法中返回多个值的三种方法(转载) IEnumerable,ICollection,IList接口问题 不吹不擂,你想要的Python面试都在这里了【315+道题】 基于mvc三层架构和ajax技术实现最简单的文件上传 事件管理
服务器文档下载zip格式 刚好这次项目中遇到了这个东西,就来弄一下,挺简单的,但是前台调用的时候弄错了,浪费了大半天的时间,本人也是菜鸟一枚.开始吧.(MVC的) @using Rattan.Co ...
- 【奇淫技巧】API接口字段table文档转代码工具
今天做一个视频接口对接,发现对方提供的文档没有json格式,无法自动生成请求和响应对象 json自动生成C#类的工具 http://tool.sufeinet.com/Creater/JsonClas ...
- [转]支付宝接口程序、文档及解读(ASP.NET)
本文转自:http://www.cnblogs.com/blodfox777/archive/2009/11/03/1595223.html 最近需要为网站加入支付宝的充值接口,而目前关于支付宝接口开 ...
- <<海闻电子发票接口 ESB 封装文档>>
<<海闻电子发票接口 ESB 封装文档>> 章节目录结构: 发票验证接口 发票开具接口 ESB请求地址: 发票验证接口: http://10.15.22.120:8866/42 ...
- 支付宝接口程序、文档及解读(ASP.NET)
最近需要为网站加入支付宝的充值接口,而目前关于支付宝接口开发的资料比较杂乱,这里就我此次开发所用到的资料进行汇总整理,希望能够帮助需要的朋友. 开发步骤: 1. 确定签约类型 支付宝的接口有多种类型, ...
- 数字麦克风PDM转PCM与STM32 I2S接口应用----重要文档列表
数字麦克风PDM脉冲到PCM信号需要一个二次采样,ST 提过了PDM2PCM的软件包,可以完成上面的工作.软件包源码没有开源,使用手册也简洁的让人抓狂,我觉得可能是因为ST更高级的MCU直接带了硬解码 ...
- Anakia 转换xml文档为其他格式
一.简介 Anakia 使用JDOM 和Velocity将XML文档转换为特定格式的文档 二.解析xml文档方法 1.DOM java jdk,xml-api.jar 需要加载整个xml文档来构建层次 ...
- WebApi生成在线API文档--Swagger
1.前言 1.1 SwaggerUI SwaggerUI 是一个简单的Restful API 测试和文档工具.简单.漂亮.易用(官方demo).通过读取JSON 配置显示API. 项目本身仅仅也只依赖 ...
- webAPI 自动生成帮助文档
之前在项目中有用到webapi对外提供接口,发现在项目中有根据webapi的方法和注释自动生成帮助文档,还可以测试webapi方法,功能很是强大,现拿出来与大家分享一下. 先看一下生成的webapi文 ...
随机推荐
- Java NIO的工作方式
1.BIO带来的挑战 BIO即阻塞IO,不管是磁盘IO,还是网络IO,数据在写入OutputStream或者从InputStream读取时都有可能发生阻塞,一旦有阻塞,当前线程将会被挂起,即线程进入非 ...
- Apache-Flink深度解析-DataStream-Connectors之Kafka
Kafka 简介 Apache Kafka是一个分布式发布-订阅消息传递系统. 它最初由LinkedIn公司开发,LinkedIn于2010年贡献给了Apache基金会并成为顶级开源项目.Kafka用 ...
- 一个注意事项:内部类引用的外部变量必须是final的
之前写过一个项目,好久没更新了,最近翻起以前的代码,发现在这里报了一个错.(现在转到Intellij了,从前在Eclipse luna中是可以编译通过的,Eclipse mars也会报错,JDK版本都 ...
- OJ:奇怪的类复制
描述 程序填空,使其输出9 22 5 #include <iostream> using namespace std; class Sample { public: int v; // 在 ...
- 以 SPI 方式获取 SD 卡容量(V2.0)
下面是 SD 卡 V2.0 协议的 CSD 寄存器内容,来自官方手册: 单片机如何确定当前的 SD 卡遵循 V2.0 协议 CSD 寄存器为 128 个位,即 16 个字节.通过检测 CSD 寄存器的 ...
- 【转载】C#生成图片的缩略图
图片处理是C#程序开发中时常会涉及到的一个业务,除了图像的上传.保存以及下载等功能外,根据上传的图片生成一个缩略图也是常见业务,在C#语言中,可以通过Image类提供的相关方法对图片进行操作,如指定宽 ...
- innodb mvcc实现机制
多版本并发控制 大部分的MySQL的存储 引擎,比如InnoDB,Falcon,以及PBXT并不是简简单单的使用行锁机制.它们都使用了行锁结合一种提高并发的技术,被称为MVCC(多版本并 发控制).M ...
- 小兔的棋盘(hdu2067)
小兔的棋盘 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- JavaScript碎片—函数闭包(模拟面向对象)
经过这几天的博客浏览,让我见识大涨,其中有一篇让我感触犹深,JavaScript语言本身是没有面向对象的,但是那些大神们却深深的模拟出来了面向对象,让我震撼不已.本篇博客就是在此基础上加上自己的认知, ...
- HTML float 和 absolute
block元素和inline元素在文档流中的排列方式: block元素通常被现实为独立的一块,独占一行,多个block元素会各自新起一行,默认block元素宽度自动填满其父元素宽度.block元素可以 ...