tnblog
首页
视频
资源
登录

使用swagger创建webapi文档描述---详解

9948人阅读 2019/4/23 15:24 总访问:144533 评论:2 收藏:1 手机
分类: C#

在前后端分离开发中,作为后端如何给前端提供有效直观的接口文档呢?

没错,就是使用swagger 俗称“丝袜哥”


教程:

一、首先我们建立一个webapi项目,然后引用需要包。swagger需引用下面这2个包

卸载重复包(提示:这里直接卸载是卸载不掉的,这个包是依赖于Swagger.Net.UI这个包的,所以我们要勾选中强制删除,然后再删):

swaggUI这个文件夹也没用,删掉


二、写一个测试用的接口:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Net;
  5. using System.Net.Http;
  6. using System.Web.Http;
  7. namespace webApiTest.Areas.Test.Controllers
  8. {
  9.   ///<summary>
  10.   ///测试接口
  11.   ///</summary
  12.   public class TestController : ApiController
  13.   {
  14.     ///<summary>
  15.     ///测试接口
  16.     ///</summary>
  17.     ///<param name="name">姓名</param>
  18.     ///<returns>返回问候语</returns>
  19.      [Route("v1.0/SendVer"), HttpGet]
  20.     public string SayHello(string name)
  21.     {
  22.       return "Hello," + name;
  23.     }
  24.   }
  25. }


默认的路由地址是:http://xxx/Swagger 访问一下已可以到接口描述:

三、现在已经有了接口描述,为了更加直观可视,我们还需重写下路由和进行汉化处理


1、首先加载汉化包:可以到我的百度网盘去下:

            链接:https://pan.baidu.com/s/1nCBGIQ1_OWi6Ly8Ta84IzQ 

            提取码:epxz

      下载完成后放到项目Scripts文件夹中去:

        

      有了汉化文件,我们就来加载到项目中去,重写 swaggerConfig.cs文件,打开后发现一堆英文注释,看不球懂,自己翻译了整理下(

       只翻译了部分我用到的,看实际情况食用):

  1. using System.Web.Http;
  2. using WebActivatorEx;
  3. using webApiTest;
  4. using Swashbuckle.Application;
  5. using System;
  6. using Swashbuckle.Swagger;
  7. using System.Xml;
  8. using System.Collections.Concurrent;
  9. using System.IO;
  10. using System.Collections.Generic;
  11. [assembly: PreApplicationStartMethod(typeof(SwaggerConfig), "Register")]
  12. namespace webApiTest
  13. {
  14.   public class SwaggerConfig
  15.   {
  16.     public static void Register()
  17.     {
  18.       var thisAssembly = typeof(SwaggerConfig).Assembly;
  19.       GlobalConfiguration.Configuration
  20.         .EnableSwagger(c =>
  21.         {
  22.           //默认情况下,服务根url推断从请求用于访问文档。然而,可能存在的情况下(如代理和负载均衡环境),这确实notresolve正确。
  23.           //你可以解决这个通过提供您自己的代码来确定根URL。
  24.           //c.RootUrl(req => GetRootUrlFromAppConfig());
  25.           //如果Swagger2.0提供的文档不明确,然后计划用于访问文档作为默认值。
  26.           //如果您的API支持多个计划和你想要明确的,您可以使用“方案”选项如下所示。
  27.           //c.Schemes(new[] { "http", "https" });
  28.           //使用“SingleApiVersion”来描述一个版本的API。Swagger2.0包含一个“信息”对象持有额外的元数据API。
  29.           //版本和标题是必需的,但是您还可以提供额外的字段SingleApiVersion链接方法。
  30.           c.SingleApiVersion("v1""");
  31.           //如果希望输出Swagger文档正确缩进,请启用“PrettyPrint”选项。
  32.           //c.PrettyPrint();
  33.           //如果您的API有多个版本,使用“MultipleApiVersions”而不是“SingleApiVersion”。
  34.           //在这种情况下,您必须提供一个告诉Swagger的行为应该被包括在给定API版本的文档。
  35.           //像“SingleApiVersion”,每次调用“版本”返回一个“信息”构建器可以提供额外的元数据API版本
  36.           //c.MultipleApiVersions(
  37.           //  (apiDesc, targetApiVersion) => ResolveVersionSupportByRouteConstraint(apiDesc, targetApiVersion),
  38.           //  (vc) =>
  39.           //  {
  40.           //    vc.Version("v2", "Swashbuckle Dummy API V2");
  41.           //    vc.Version("v1", "Swashbuckle Dummy API V1");
  42.           //  });
  43.           //您可以使用“BasicAuth”、“ApiKey”或“OAuth2”选项来描述API的安全方案。
  44.           //详细信息,请参阅https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md。
  45.           //注意:这些只定义相对应的方案,需要加上一个“安全”属性的文档或操作水平,表明该方案所需的操作。
  46.           //要做到这一点,你需要实现一个自定义IDocumentFilter和/或IOperationFilter根据您特定的授权设置这些属性实现
  47.           //c.BasicAuth("basic")
  48.           // .Description("Basic HTTP Authentication");
  49.           //
  50.           //注意:您还必须在SwaggerUI部分下面配置“EnableApiKeySupport”
  51.           //c.ApiKey("apiKey")
  52.           // .Description("API Key Authentication")
  53.           // .Name("apiKey")
  54.           // .In("header");
  55.           //
  56.           //c.OAuth2("oauth2")
  57.           // .Description("OAuth2 Implicit Grant")
  58.           // .Flow("implicit")
  59.           // .AuthorizationUrl("http://petstore.swagger.wordnik.com/api/oauth/dialog")
  60.           //  .TokenUrl("https://tempuri.org/token")
  61.           // .Scopes(scopes =>
  62.           //  {
  63.           //     scopes.Add("read", "Read access to protected resources");
  64.           //   scopes.Add("write", "Write access to protected resources");
  65.           // });
  66.                     //这个标志设置为省略过时的属性描述的任何行动
  67.           //c.IgnoreObsoleteActions();
  68.           //每个操作被分配一个或多个标签,然后用消费者出于各种原因。例如,swagger-ui组操作根据每个操作的第一个标记。
  69.           //默认情况下,这将是控制器的名字,但您可以使用“GroupActionsBy”选项与任何值覆盖。
  70.           //c.GroupActionsBy(apiDesc => apiDesc.HttpMethod.ToString());
  71.           //你也可以指定一个自定义的排序顺序组(定义为“GroupActionsBy”)规定的顺序列出操作。
  72.           //例如,如果默认分组(控制器名称)和您指定一个下行字母排序,然后从aProductsController行动将从CustomersController上市之前。
  73.           //这是通常用于定制swagger -ui分组的顺序。
  74.           //c.OrderActionGroupsBy(new DescendingAlphabeticComparer());
  75.           //如果您用它来注释控制器和API类型
  76.           //Xml注释(http://msdn.microsoft.com/en-us/library/b2s063f7(v=vs.110).aspx),可以合并
  77.           //将这些注释添加到生成的文档和UI中。您可以通过提供到one或更多的Xml注释文件。
  78.           //c.IncludeXmlComments(GetXmlCommentsPath());
  79.           //Swashbuckle尽力为各种类型生成与Swagger兼容的JSON模式在您的API中公开。然而,有时可能需要对输出进行更多的控制。
  80.           //这是通过“MapType”和“SchemaFilter”选项支持的:使用“MapType”选项覆盖特定类型的模式生成。
  81.           //需要注意的是,对于任何适用的操作,生成的模式都将放在“内联”位置。
  82.           //虽然Swagger 2.0支持“所有”模式类型的内联定义,但是Swagger -ui工具不支持。
  83.           //它期望“复杂”模式被单独定义和引用。出于这个原因,你只应该当得到的模式是基本类型或数组类型时,
  84.           //使用“MapType”选项。如果你需要改变复杂模式,使用模式过滤器。
  85.           //c.MapType<ProductType>(() => new Schema { type = "integer", format = "int32" });
  86.           //这个是webApiTest接口这个项目的XML文档
  87.           c.IncludeXmlComments(string.Format("{0}/bin/webApiTest.XML", AppDomain.CurrentDomain.BaseDirectory));
  88.           //这个是实体类的XML文档,因为在实际中我们需要调用实体类库,我这里只是个简单的例子,所以没有使用到这个
  89.           //c.IncludeXmlComments(string.Format("{0}/bin/Model.XML", AppDomain.CurrentDomain.BaseDirectory));
  90.           c.CustomProvider((defaultProvider) => new CachingSwaggerProvider(defaultProvider));
  91.         })
  92.         //重新定义路径及汉化文件
  93.         .EnableSwaggerUi("apis/{*assetPath}", c =>
  94.         {
  95.             //这里代表你汉化文件的存放路径,这里有一个坑,当解决方案有'.'这种字符的时候会给识别为路径,且没办法转义,
  96.           //这个坑的我好惨,比如解决方案改为webapi.test 就要出事了
  97.           //路径规则,项目命名空间.文件夹名称.js文件名称
  98.           c.InjectStylesheet(thisAssembly, "webApiTest.Scripts.custom.css");
  99.           c.InjectJavaScript(thisAssembly, "webApiTest.Scripts.swagger_lang.js");
  100.           //c.CustomAsset("index", thisAssembly, "NineTeam.API.Swagger.index.html");
  101.         });
  102.       }
  103.       ///<summary>
  104.       ///Swagger汉化
  105.       ///</summary>
  106.       public class CachingSwaggerProvider : ISwaggerProvider
  107.       {
  108.           private static ConcurrentDictionary<string, SwaggerDocument> _cache =
  109.         new ConcurrentDictionary<string, SwaggerDocument>();
  110.         private readonly ISwaggerProvider _swaggerProvider;
  111.         public CachingSwaggerProvider(ISwaggerProvider swaggerProvider)
  112.         {
  113.           _swaggerProvider = swaggerProvider;
  114.         }
  115.         public SwaggerDocument GetSwagger(string rootUrl, string apiVersion)
  116.         {
  117.           var cacheKey = string.Format("{0}_{1}", rootUrl, apiVersion);
  118.           SwaggerDocument srcDoc = null;
  119.           //只读取一次
  120.           if(!_cache.TryGetValue(cacheKey, out srcDoc))
  121.           {
  122.             srcDoc = _swaggerProvider.GetSwagger(rootUrl, apiVersion);
  123.             srcDoc.vendorExtensions = new Dictionary<stringobject> { { "ControllerDesc", GetControllerDesc() } };
  124.               _cache.TryAdd(cacheKey, srcDoc);
  125.           }
  126.           return srcDoc;
  127.         }
  128.         ///<summary>
  129.         ///从API文档中读取控制器描述
  130.         ///</summary>
  131.         ///<returns>所有控制器描述</returns>
  132.         public static ConcurrentDictionary<stringstringGetControllerDesc()
  133.         {
  134.           string xmlpath = string.Format(@"{0}\bin\webApiTest.XML", System.AppDomain.CurrentDomain.BaseDirectory);
  135.           ConcurrentDictionary<stringstring> controllerDescDict = new ConcurrentDictionary<stringstring>();
  136.           if (File.Exists(xmlpath))
  137.           {
  138.             XmlDocument xmldoc = new XmlDocument();
  139.             xmldoc.Load(xmlpath);
  140.             string type = string.Empty, path = string.Empty, controllerName = string.Empty;
  141.             string[] arrPath;
  142.             int length = -1, cCount = "Controller".Length;
  143.             XmlNode summaryNode = null;
  144.             foreach (XmlNode node in xmldoc.SelectNodes("//member"))
  145.             {
  146.             type = node.Attributes["name"].Value;
  147.             if (type.StartsWith("T:"))
  148.             {
  149.               //控制器
  150.               arrPath = type.Split('.');
  151.               length = arrPath.Length;
  152.               controllerName = arrPath[length - 1];
  153.               if (controllerName.EndsWith("Controller"))
  154.               {
  155.                 //获取控制器注释
  156.                 summaryNode = node.SelectSingleNode("summary");
  157.                 string key = controllerName.Remove(controllerName.Length - cCount, cCount);
  158.                 if (summaryNode != null && !string.IsNullOrEmpty(summaryNode.InnerText) && !controllerDescDict.ContainsKey(key))
  159.                 {
  160.                     controllerDescDict.TryAdd(key, summaryNode.InnerText.Trim());
  161.                   }
  162.               }
  163.             }
  164.           }
  165.         }
  166.         return controllerDescDict;
  167.       }
  168.     }
  169.   }
  170. }

 2、认真看了代码的童鞋可能已经发现,swagger的原理实际上就是读取你在编写代码时编写的注释,所以你的注释得详细,那么如何生成XML文件?

       右键项目属性》生成》:

重新生成下项目,可以看到bin文件夹下已生成xml文件,打开看一下是什么东西:

可以到在末尾有我们刚才接口的注释。嗯~感觉是搭建的差不多了,跑一下:

   汉化怎么没成???但是文档的注释是加载进来了。重新检查下路径发现也是对的?

                怎么办呢,别急,只需要改下这两个文件的生产操作:

右键这两个文件》属性》生成操作》改为嵌入式


OK!再试一下:


嗯~这就美观多了。


总结:实践是检验真理的唯一标准!





评价

饰心

2019/4/23 15:57:59

WebApiTestClient也是一种方式,http://www.cnblogs.com/landeanfen/p/5210356.html

剑轩

2019/4/23 19:45:47

mark,后面看[给力]

NET Core 使用 EF Code First

下面这些内容很老了看这篇:https://www.tnblog.net/aojiancc2/article/details/5365 项目使用多层,把数据库访问...

使用OLEDB读取不同版本Excel的连接字符串设置

使用OleBD读取excel的时候,excel不同的版本,连接字符串的写法也会不一样。///&lt;summary&gt; ///读取excel ///&lt;/su...

C 使用CancellationTokenSource取消多线程

有时间我们在使用多线程的时候,需要取消线程的执行,可以使用CancellationTokenSource来取消对Task开辟多线程的取消如下:...

使用爬虫刷csdn博客访问量

首先了解一下常见反爬虫的检测方法频率监测:有些网站会设置一种频率监测的机制,对于同一IP,若在一定时间内访问的速度超...

Idea下使用maven搭建SSM(一):SpringMVC

Spring MVC是一款基于MVC架构模式的轻量级Web框架,其目的是将Web开发模块化,对整体架构进行解耦,简化Web开发流程。下面...

Idea下使用maven搭建SSM(二):MyBatis

开发Web应用,数据的存储和处理往往离不开数据库和SQL语句。在使用Java开发的Web应用中,自然也少不了连接数据库的步骤。在...

使用 微软自带语音合成类库

//引入语音合成名称空间 usingSystem.Speech.Synthesis; classA { voidtest1() { //实例化并指定字符串播放合成读音 ...

如何使用图标像使用文字一样,使用文本图标的方法

1.首先在Iconfont-阿里巴巴矢量图标库上面找到你需要的图标然后加入你的购物车然后选择图标;注意:每个类型的图标会大小不...

使用七牛云的cdn服务,提高图片的加载速度

CDN介绍CDN的全称是Content Delivery Network,即内容分发网络。CDN加速主要是加速静态资源,如网站上面上传的图片、媒体,...

.net core 使用session

tip:net core 2.2后可以直接启用session了,不用在自己添加一次session依赖,本身就添加了使用nuget添加引用Microsoft.AspN...

使用OutLook发送邮件

publicstaticvoidOutlook(stringSubject,stringTextBody,stringFromAdd,stringFromPass,stringTo,stringCC,List&lt;string&...

SQL Server 中使用游标

--声明一个游标 DECLAREMyCursorCURSOR FORSELECTTOP5FBookName,FBookCodingFROMTBookInfo//定义一个叫MyCursor的游标,...

Windows使用wireshark抓包小心得

wireshrak是个网络抓包工具,常用。但是在数据较大的网络环境中直接使用软件抓包会导致wireshark卡死。为什么呢 ?网卡瞬间...

Oracle自定义函数的简单使用

一.最最最简单的返回一个数字的函数createorreplacefunctionfun_show returnint--申明返回值 as begin return1; end;...

Oracle事务的简单使用

事务:  事务是一个整体,这些操作要么全部执行成功,要么全部不执行。使用事务的原因:保证数据的安全有效。事务的四个特...

Oracle使用游标

其实游标就是把查询的结果放入游标中,然后在去游标里边读取。相当于使用游标做了一个中转,而游标是可以作为参数进行传递...
Decorating heart
排名
22
文章
14
粉丝
21
评论
27
腾讯防水墙
赖成龙 : 学长你有下载好的js文件吗
使用 JSON WEB TOKEN (jwt) 验证
饰心 : 由于最近换了新的工作环境,还在挖煤中。后续会增加博客更新频率。
腾讯防水墙
饰心 : @剑轩,快去给tnblog弄一个
使用select2实现下拉框中显示图片
剑轩 : 秀啊.....,飞常不错
使用select2实现下拉框中显示图片
饰心 : 嗯~刚好差不多下班
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术
你还有好多未完成的梦,你有什么理由停下脚步