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 包管理软件,查 ...
随机推荐
- java设计模式---桥接模式
桥接模式的目的是把抽象和具体实现分离,其uml类图如下所示: public interface SendMessage { abstract void send(String message,Stri ...
- 12.2、Libgdx的图像之清屏
(官网:www.libgdx.cn) 在Libgdx中的清屏操作不同于普通的OpenGL应用.唯一的不同是访问OpenGL context. 代码如下: @Override public void r ...
- UI设计——最后一根稻草
WindowsLive提供的本地地图服务看起来挺简单的,但其实非常难用: 跟其他人一样,每当我接触到一个新的地图服务,我做的第一件事总是拿当前的地址去试一试.我在上面输入的是我工作的地方.但是,当我敲 ...
- 72【leetcode】经典算法- Lowest Common Ancestor of a Binary Search Tree(lct of bst)
题目描述: 一个二叉搜索树,给定两个节点a,b,求最小的公共祖先 _______6______ / \ ___2__ ___8__ / \ / \ 0 _4 7 9 / \ 3 5 例如: 2,8 - ...
- 【翻译】Ext JS最新技巧——2014-9-10
原文:Top Support Tips Greg Barry:删除网格单元格的焦点 在Ext JS 5.0.1,添加了一些与可访问性和支持ARIA有关的显著改进.虽然鼓励使用这些新增功能,但默认样式可 ...
- visual svn使用教程
SVN简介: 为什么要使用SVN? 程序员在编写程序的过程中,每个程序员都会生成很多不同的版本,这就需要程序员有效的管理代码,在需要的时候可以迅速,准确取出相应的版本. Subversion是什 ...
- Memcached的配置,SSH项目中的整合(com.whalin),Memcached工具类,Memcached的代码调用
1 修改pom.xml,添加依赖文件: <dependency> <groupId>com.whalin</groupId> <artifactId&g ...
- 11_Eclipse中演示Git版本的创建,历史版本的修改,创建分支,合并历史版本和当前版本
1 执行以下案例: 某研发团队2011年初开发了一款名为Apollo的信息系统,目前已发布v1.0版本.此项目初期已有部分基础代码, 研发团队再此基础代码上经过3个月的努力发布了一个功能相对完备 ...
- libevent之eventop
在之前博文libevent之Reactor模式中,我们知道Reactor模式中一个重要的组件就是事件多路分发机制(event demultiplexer).而在libevent中,对事件多路分发机制的 ...
- 【matlab编程】matlab随机数函数
Matlab内部函数 a. 基本随机数 Matlab中有两个最基本生成随机数的函数. 1.rand() 生成(0,1)区间上均匀分布的随机变量.基本语法: rand([M,N,P ...]) 生成排列 ...