Asp.Net WebApi Swagger终极搭建
【PS:原文手打,转载说明出处,博客园】
关于为什么用Swagger
目前稍微有点规模的公司,已经从原先的瀑布流开发到了敏捷开发,实现前后端分离,为此后端工程师只关注写好Api即可,那程序员最讨厌的就是写Api文档了,故而产生了Swagger。
Swagger原理
Swagger就是利用反射技术遍历所有Api接口,并且从xml文件中读取注释,在利用Swagger内置的模板组合html显示至客户端实现接口可视化,并且可调用。
Asp.net WebApi Swagger集成
1:vs2017,新建web项目,选择WebApi
2:删除Views、Scripts、Models、fonts、Content、Areas目录
3:删除RouteConfig.cs、FilterConfig.cs、BundleConfig.cs
4:删除HomeController.cs
5:Global.asax中删除异常代码
6:nuget搜索Swagger,安装 Swashbuckle
7:右键项目——》属性——》生成——》输出——》勾选XML文档文件——》保存
8:修改SwaggerConfig.cs
新增方法,释放c.IncludeXmlComments(GetXmlCommentsPath());的注释(注意:例如返回值为对象,然后又不在同一个项目,则需要多次调用)
- private static string GetXmlCommentsPath()
- {
- return System.String.Format(@"{0}\bin\{项目名称}.XML",
- System.AppDomain.CurrentDomain.BaseDirectory);
- }
9:然后在url地址中:例如:http://localhost:port/swagger即可
Swagger进阶
1:当有dto项目时,此时dto也需要把注释打到客户端,注意dto项目也参考上面第7点生成xml文件,复制第8点的方法
2:Swagger新增Header信息,在上方注释的地方加入:c.OperationFilter<HttpHeaderFilter>(); 拷贝下方代码
- public class HttpHeaderFilter : IOperationFilter
- {
- public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
- {
- if (operation.parameters == null)
- operation.parameters = new List<Parameter>();
- var filterPipeline = apiDescription.ActionDescriptor.GetFilterPipeline(); //判断是否添加权限过滤器
- var isAuthorized = filterPipeline.Select(filterInfo => filterInfo.Instance)
- .Any(filter => filter is ErpFilterAttribute); //判断是否允许匿名方法
- //var allowAnonymous = apiDescription.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any();
- if (isAuthorized)
- {
- operation.parameters.Add(new Parameter
- {
- name = "AppId",
- @in = "header",
- description = "应用ID(机构编号)",
- required = false,
- type = "string"
- });
- operation.parameters.Add(new Parameter
- {
- name = "Version",
- @in = "header",
- description = "版本号",
- required = false,
- type = "string"
- });
- operation.parameters.Add(new Parameter
- {
- name = "Ts",
- @in = "header",
- description = "时间戳",
- required = false,
- type = "string"
- });
- operation.parameters.Add(new Parameter
- {
- name = "Lang",
- @in = "header",
- description = "语言包",
- required = false,
- type = "string"
- });
- operation.parameters.Add(new Parameter
- {
- name = "Sign",
- @in = "header",
- description = "签名",
- required = false,
- type = "string"
- });
- return;
- }
- }
- }
3:注释的用法
注释的用法,在API接口中"///"三斜杠注释的summary为接口名注释,summary下回车<remarks>为备注,注意每个字段的注释必须要全面,否则无法显示完全
参考代码如下
- /// <summary>
- /// 角色 分页列表
- /// </summary>
- /// <remarks>
- /// Code返回值说明:
- ///
- /// 错误码地址:http://xxxx.com/
- ///
- /// </remarks>
- /// <param name="conditionModel">分页查询条件</param>
- /// <returns></returns>
- [HttpGet, Route("api/ClientRoles")]
- public OutputModel<PagingOutputModel<List<BaseRoleDto>>> GetRoleList([FromUri]PagingInputModel conditionModel)
- {
- return null;
- }
4:显示控制器注释
新建:CachingSwaggerProvider.cs,代码如下 注意Mike.Merchant.WebApi.XML需要替换成你本地的工程目录
- using System;
- using System.Collections.Concurrent;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using System.Xml;
- using Swashbuckle.Swagger;
- using System.IO;
- namespace Mike.Merchant.WebApi
- {
- public class CachingSwaggerProvider : ISwaggerProvider
- {
- private static ConcurrentDictionary<string, SwaggerDocument> _cache =
- new ConcurrentDictionary<string, SwaggerDocument>();
- private readonly ISwaggerProvider _swaggerProvider;
- public CachingSwaggerProvider(ISwaggerProvider swaggerProvider)
- {
- _swaggerProvider = swaggerProvider;
- }
- public SwaggerDocument GetSwagger(string rootUrl, string apiVersion)
- {
- var cacheKey = string.Format("{0}_{1}", rootUrl, apiVersion);
- SwaggerDocument srcDoc = null;
- //只读取一次
- if (!_cache.TryGetValue(cacheKey, out srcDoc))
- {
- srcDoc = _swaggerProvider.GetSwagger(rootUrl, apiVersion);
- srcDoc.vendorExtensions = new Dictionary<string, object> { { "ControllerDesc", GetControllerDesc() } };
- _cache.TryAdd(cacheKey, srcDoc);
- }
- return srcDoc;
- }
- /// <summary>
- /// 从API文档中读取控制器描述
- /// </summary>
- /// <returns>所有控制器描述</returns>
- public static ConcurrentDictionary<string, string> GetControllerDesc()
- {
- string xmlpath = string.Format("{0}/bin/Mike.Merchant.WebApi.XML", System.AppDomain.CurrentDomain.BaseDirectory);
- ConcurrentDictionary<string, string> controllerDescDict = new ConcurrentDictionary<string, string>();
- if (File.Exists(xmlpath))
- {
- XmlDocument xmldoc = new XmlDocument();
- xmldoc.Load(xmlpath);
- string type = string.Empty, path = string.Empty, controllerName = string.Empty;
- string[] arrPath;
- int length = -, cCount = "Controller".Length;
- XmlNode summaryNode = null;
- foreach (XmlNode node in xmldoc.SelectNodes("//member"))
- {
- type = node.Attributes["name"].Value;
- if (type.StartsWith("T:"))
- {
- //控制器
- arrPath = type.Split('.');
- length = arrPath.Length;
- controllerName = arrPath[length - ];
- if (controllerName.EndsWith("Controller"))
- {
- //获取控制器注释
- summaryNode = node.SelectSingleNode("summary");
- string key = controllerName.Remove(controllerName.Length - cCount, cCount);
- if (summaryNode != null && !string.IsNullOrEmpty(summaryNode.InnerText) && !controllerDescDict.ContainsKey(key))
- {
- controllerDescDict.TryAdd(key, summaryNode.InnerText.Trim());
- }
- }
- }
- }
- }
- return controllerDescDict;
- }
- }
- }
新建:swagger_show.js,代码如下
- var ControllerSummary = function () {
- var urlval = $("#input_baseUrl").val()
- $.ajax({
- type: "get",
- async: true,
- url: urlval,
- dataType: "json",
- success: function (data) {
- var summaryDict = data.ControllerDesc;
- var id, controllerName, strSummary;
- $("#resources_container .resource").each(function (i, item) {
- id = $(item).attr("id");
- if (id) {
- controllerName = id.substring();
- strSummary = summaryDict[controllerName];
- if (strSummary) {
- $(item).children(".heading").children(".options").prepend('<li style="color:red;" class="controller-summary" title="' + strSummary + '">' + strSummary + '</li>');
- }
- }
- });
- }
- });
- }
- ControllerSummary()
打开SwaggerConfig.cs 代码如下
注意代码:c.InjectJavaScript(thisAssembly, "Mike.Merchant.WebApi.Scripts.swagger_show.js");
后面的这个为工程目录.文件夹.js。
- GlobalConfiguration.Configuration
- .EnableSwagger(c =>
- {
- c.SingleApiVersion("v1", "Api文档");
- c.OperationFilter<HttpHeaderFilter>();
- c.IncludeXmlComments(GetXmlCommentsPath());
- //c.IncludeXmlComments(GetDtoXmlCommentsPath());
- c.CustomProvider((defaultProvider) => new CachingSwaggerProvider(defaultProvider));
- })
- .EnableSwaggerUi(c =>
- {
- c.DocumentTitle("Api文档");
- c.InjectJavaScript(thisAssembly, "Mike.Merchant.WebApi.Scripts.swagger_show.js");
- });
图片展示
Asp.Net WebApi Swagger终极搭建的更多相关文章
- Asp.Net WebApi swagger使用教程
swagger简介 别名:丝袜哥 功能:用于生产api文档 swagger安装 Nuget搜索swagger,然后安装Swashbuckle swagger使用 生成api的xml文档 webapi项 ...
- ASP.NET WebApi+Vue前后端分离之允许启用跨域请求
前言: 这段时间接手了一个新需求,将一个ASP.NET MVC项目改成前后端分离项目.前端使用Vue,后端则是使用ASP.NET WebApi.在搭建完成前后端框架后,进行接口测试时发现了一个前后端分 ...
- ASP.NET WebApi 文档Swagger深度优化
本文版权归博客园和作者吴双本人共同所有,转载和爬虫请注明博客园蜗牛原文地址,cnblogs.com/tdws 写在前面 请原谅我这个标题党,写到了第100篇随笔,说是深度优化,其实也并没有什么深度 ...
- ASP.NET WebApi 文档Swagger中度优化
本文版权归博客园和作者吴双本人共同所有,转载和爬虫请注明原文地址:www.cnblogs.com/tdws 写在前面 在后台接口开发中,接口文档是必不可少的.在复杂的业务当中和多人对接的情况下,简 ...
- ASP.NET WebAPI 生成帮助文档与使用Swagger服务测试
帮助HELP 要实现如WCF中的Help帮助文档,Web API 2 中已经支持很方便的实现了这一特性 http://www.asp.net/web-api/overview/creating-we ...
- ASP.NET WebAPI使用Swagger生成测试文档
ASP.NET WebAPI使用Swagger生成测试文档 SwaggerUI是一个简单的Restful API测试和文档工具.简单.漂亮.易用(官方demo).通过读取JSON配置显示API .项目 ...
- ASP.NET WebAPI 集成 Swagger 启用 OAuth 2.0 配置问题
在 ASP.NET WebAPI 集成 Swagger 后,由于接口使用了 IdentityServer 做的认证,调试起来很不方便:看了下 Swashbuckle 的文档 ,是支持 OAuth2.0 ...
- ASP.NET WebAPI 测试文档 (Swagger)
ASP.NET WebAPI使用Swagger生成测试文档 SwaggerUI是一个简单的Restful API测试和文档工具.简单.漂亮.易用(官方demo).通过读取JSON配置显示API .项目 ...
- ASP.NET WebApi 中使用swagger 构建在线帮助文档
1 在Visual Studio 中创建一个Asp.NET WebApi 项目,项目名:Com.App.SysApi(本例创建的是 .net 4.5 框架程序) 2 打开Nuget 包管理软件,查 ...
随机推荐
- Spark程序开发-环境搭建-程序编写-Debug调试-项目提交
1,使用IDEA软件进行开发. 在idea中新建scala project, File-->New-->Project.选择Scala-->Scala 2,在编辑窗口中完成Word ...
- SpriteBuilder中使用Node类型的ccb动画节点删除时崩溃的问题
因为节点需要呈现动画效果,虽然只有两个不同帧. 在SpriteBuilder中新建Bullet.ccb文件,类型为node. 添加如上2张图片,并制作动画效果帧. 在游戏中子弹遇到障碍物会被删除,时机 ...
- Java进阶(四)Java反射TypeToken解决泛型运行时类型擦除问题
在开发时,遇到了下面这条语句,不懂,然习之. private List<MyZhuiHaoDetailModel> listLottery = new ArrayList<MyZhu ...
- 11.3、Libgdx的音频之播放PCM音频
(官网:www.libgdx.cn) audio模块可以提供对音频硬件的直接访问. 音频硬件是通过AudioDevice接口进行的抽象. 以下创建一个新的AudioDevice实例: AudioDev ...
- 小强的HTML5移动开发之路(19)——HTML5 Local Storage(本地存储)
来自:http://blog.csdn.net/dawanganban/article/details/18218701 一.浏览器存储的发展历程 本地存储解决方案很多,比如Flash SharedO ...
- Linux进程实践(1) --Linux进程编程概述
进程 VS. 程序 什么是程序? 程序是完成特定任务的一系列指令集合. 什么是进程? [1]从用户的角度来看:进程是程序的一次执行过程 [2]从操作系统的核心来看:进程是操作系统分配的内存.CPU时间 ...
- python爬虫 - python requests网络请求简洁之道
http://blog.csdn.net/pipisorry/article/details/48086195 requests简介 requests是一个很实用的Python HTTP客户端库,编写 ...
- JQuery实战总结三 标签页效果图实现
在浏览网站时我们会看到当我们鼠标移到多个选项卡上时,不同的选项卡会出现自己对应的界面的要求,在同一个界面上表达了尽量多的信息.大大额提高了空间的利用率.界面的切换效果也是不错的哦,这次自己可以实现啦. ...
- opencv读写视频,对感兴趣区域进行裁剪
作为小码农,本人最近想对一段视频的某个区域进行处理,因此要将该段视频区域裁剪出来,搜搜网上,发现没有痕迹,是故自己琢磨一下,左右借鉴,编了如下代码,目标得以实现,希望对你有用. #include &q ...
- 如何成为Android高手
要成为Android 高手并不是一件容易的事情.并不是很多人想象的 能够飞快的写出几行漂亮的代码去解决一些困难的问题 就是Android 高手了.真正的Android 高手需要考虑的问题远远不是写些漂 ...