【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终极搭建的更多相关文章

  1. Asp.Net WebApi swagger使用教程

    swagger简介 别名:丝袜哥 功能:用于生产api文档 swagger安装 Nuget搜索swagger,然后安装Swashbuckle swagger使用 生成api的xml文档 webapi项 ...

  2. ASP.NET WebApi+Vue前后端分离之允许启用跨域请求

    前言: 这段时间接手了一个新需求,将一个ASP.NET MVC项目改成前后端分离项目.前端使用Vue,后端则是使用ASP.NET WebApi.在搭建完成前后端框架后,进行接口测试时发现了一个前后端分 ...

  3. ASP.NET WebApi 文档Swagger深度优化

    本文版权归博客园和作者吴双本人共同所有,转载和爬虫请注明博客园蜗牛原文地址,cnblogs.com/tdws   写在前面 请原谅我这个标题党,写到了第100篇随笔,说是深度优化,其实也并没有什么深度 ...

  4. ASP.NET WebApi 文档Swagger中度优化

    本文版权归博客园和作者吴双本人共同所有,转载和爬虫请注明原文地址:www.cnblogs.com/tdws   写在前面 在后台接口开发中,接口文档是必不可少的.在复杂的业务当中和多人对接的情况下,简 ...

  5. ASP.NET WebAPI 生成帮助文档与使用Swagger服务测试

    帮助HELP 要实现如WCF中的Help帮助文档,Web API 2 中已经支持很方便的实现了这一特性  http://www.asp.net/web-api/overview/creating-we ...

  6. ASP.NET WebAPI使用Swagger生成测试文档

    ASP.NET WebAPI使用Swagger生成测试文档 SwaggerUI是一个简单的Restful API测试和文档工具.简单.漂亮.易用(官方demo).通过读取JSON配置显示API .项目 ...

  7. ASP.NET WebAPI 集成 Swagger 启用 OAuth 2.0 配置问题

    在 ASP.NET WebAPI 集成 Swagger 后,由于接口使用了 IdentityServer 做的认证,调试起来很不方便:看了下 Swashbuckle 的文档 ,是支持 OAuth2.0 ...

  8. ASP.NET WebAPI 测试文档 (Swagger)

    ASP.NET WebAPI使用Swagger生成测试文档 SwaggerUI是一个简单的Restful API测试和文档工具.简单.漂亮.易用(官方demo).通过读取JSON配置显示API .项目 ...

  9. ASP.NET WebApi 中使用swagger 构建在线帮助文档

    1 在Visual Studio 中创建一个Asp.NET  WebApi 项目,项目名:Com.App.SysApi(本例创建的是 .net 4.5 框架程序) 2  打开Nuget 包管理软件,查 ...

随机推荐

  1. Dynamics CRM2013 更新用户数据主要电子邮件字段报数据加密错误

    今天在更新用户数据中的主要邮件字段时报数据 可以进系统设置-数据管理-数据加密中开启,但前提是必须启用https访问而不能用http,在第二个框内输入秘钥点击激活就行了,我这边已经激活过了所以显示的是 ...

  2. python复杂网络库networkx:基础

    http://blog.csdn.net/pipisorry/article/details/49839251 其它复杂网络绘图库 [SNAP for python] [ArcGIS,Python,网 ...

  3. Dynamics CRM2013 1:N关系 sub-grid中的“添加现有项”和“添加新建项”功能详解

    CRM2013中sub-grid的样式和2011中有了较大的变化,2013和2011界面对比如下 在2011的时候按钮是在ribbon区,1:N的父子关系实体直接点击添加新纪录就可以,但2013就不行 ...

  4. listview异步加载图片并防止错位

    android listview 异步加载图片并防止错位 网上找了一张图, listview 异步加载图片之所以错位的根本原因是重用了 convertView 且有异步操作. 如果不重用 conver ...

  5. shell,python获取当前路径(脚本的当前路径) (aso项目记录)

    一.shell获取脚本当前路径 cur_dir=$(cd "$(dirname "$0")"; pwd)  #获取当前脚本的绝对路径,参数$0是当前脚本对象 等 ...

  6. Swift的基础之UILabel控件

    对于UILabel的相关内容,其他控件可以相似创建 //设置全局变量,将下面的 let 去掉,然后替换即可     //var myLabel = UILabel();     //系统生成的view ...

  7. 01_MUI之Boilerplate中:HTML5示例,动态组件,自定义字体示例,自定义字体示例,图标字体示例

     1安装HBuilder5.0.0,安装后的界面截图如下: 2 按照https://www.muicss.com/docs/v1/css-js/boilerplate-html中的说明,创建上图的 ...

  8. Android群英传笔记——第十二章:Android5.X 新特性详解,Material Design UI的新体验

    Android群英传笔记--第十二章:Android5.X 新特性详解,Material Design UI的新体验 第十一章为什么不写,因为我很早之前就已经写过了,有需要的可以去看 Android高 ...

  9. android资源库

    原文地址:http://blog.csdn.net/xiechengfa/article/details/38830751 在摸索过程中,GitHub上搜集了很多很棒的Android第三方库,推荐给在 ...

  10. The ENU localization is not supported by this SQL Server media

    今儿在给服务器装sqlserver2008R2时遇到一个问题"The ENU localization is not supported by this SQL Server media&q ...