Swagger生成webapi文档

WebApi接口开发完毕后,交付给前端人员或手机端开发者时接口说明文档是必不可少的配套设备,如果公司流程不规范大家使用口口相传的交接方式,而且没有改进的欲望,那你可以到此为止了。Swagger是方便测试接口,快速展示注释内容,生成Restful风格接口文档的框架。

Swagger能成为最受欢迎的REST APIs文档生成工具之一,有以下几个原因:

Swagger 可以生成一个具有互动性的API控制台,开发者可以用来快速学习和尝试API。
Swagger 可以生成客户端SDK代码用于各种不同的平台上的实现。
Swagger 文件可以在许多不同的平台上从代码注释中自动生成。
Swagger 有一个强大的社区,里面有许多强悍的贡献者。

1、安装Swashbuckle

2、初次运行 输入 自己网站地址/swagger 我这里是http://www.permissionapi.com/swagger

3、添加自定义ApiController


  
  
  1. public class AdminController : ApiController
  2. {
  3. /// <summary>
  4. /// 获取管理员信息
  5. /// </summary>
  6. /// <param name="username">管理员姓名</param>
  7. /// <param name="pwd">管理员密码</param>
  8. /// <returns></returns>
  9. public string Get(string username,string pwd)
  10. {
  11. return $"username:{username},pwd:{pwd}";
  12. }
  13. }

4、添加实现了ISwaggerProvider接口的类

在App_Start文件夹中添加SwaggerControllerDescProvider.cs,相关代码如下:


  
  
  1. namespace WebApiSwagger.Main.App_Start
  2. {
  3. /// <summary>
  4. /// 显示swagger控制器的描述
  5. /// </summary>
  6. public class SwaggerControllerDescProvider : ISwaggerProvider
  7. {
  8. private readonly ISwaggerProvider _swaggerProvider;
  9. private static ConcurrentDictionary< string, SwaggerDocument> _cache = new ConcurrentDictionary< string, SwaggerDocument>();
  10. private readonly string _xml;
  11. /// <summary>
  12. ///
  13. /// </summary>
  14. /// <param name="swaggerProvider"></param>
  15. /// <param name="xml">xml文档路径</param>
  16. public SwaggerControllerDescProvider(ISwaggerProvider swaggerProvider, string xml)
  17. {
  18. _swaggerProvider = swaggerProvider;
  19. _xml = xml;
  20. }
  21. public SwaggerDocument GetSwagger(string rootUrl, string apiVersion)
  22. {
  23. var cacheKey = string.Format( "{0}_{1}", rootUrl, apiVersion);
  24. SwaggerDocument srcDoc = null;
  25. //只读取一次
  26. if (!_cache.TryGetValue(cacheKey, out srcDoc))
  27. {
  28. srcDoc = _swaggerProvider.GetSwagger(rootUrl, apiVersion);
  29. srcDoc.vendorExtensions = new Dictionary< string, object> { { "ControllerDesc", GetControllerDesc() } };
  30. _cache.TryAdd(cacheKey, srcDoc);
  31. }
  32. return srcDoc;
  33. }
  34. /// <summary>
  35. /// 从API文档中读取控制器描述
  36. /// </summary>
  37. /// <returns>所有控制器描述</returns>
  38. public ConcurrentDictionary<string, string> GetControllerDesc()
  39. {
  40. string xmlpath = _xml;
  41. ConcurrentDictionary< string, string> controllerDescDict = new ConcurrentDictionary< string, string>();
  42. if (File.Exists(xmlpath))
  43. {
  44. XmlDocument xmldoc = new XmlDocument();
  45. xmldoc.Load(xmlpath);
  46. string type = string.Empty, path = string.Empty, controllerName = string.Empty;
  47. string[] arrPath;
  48. int length = -1, cCount = "Controller".Length;
  49. XmlNode summaryNode = null;
  50. foreach (XmlNode node in xmldoc.SelectNodes( "//member"))
  51. {
  52. type = node.Attributes[ "name"].Value;
  53. if (type.StartsWith( "T:"))
  54. {
  55. //控制器
  56. arrPath = type.Split( '.');
  57. length = arrPath.Length;
  58. controllerName = arrPath[length - 1];
  59. if (controllerName.EndsWith( "Controller"))
  60. {
  61. //获取控制器注释
  62. summaryNode = node.SelectSingleNode( "summary");
  63. string key = controllerName.Remove(controllerName.Length - cCount, cCount);
  64. if (summaryNode != null && ! string.IsNullOrEmpty(summaryNode.InnerText) && !controllerDescDict.ContainsKey(key))
  65. {
  66. controllerDescDict.TryAdd(key, summaryNode.InnerText.Trim());
  67. }
  68. }
  69. }
  70. }
  71. }
  72. return controllerDescDict;
  73. }
  74. }
  75. }

5、添加功能性js文件

在Scripts文件夹中添加SwaggerConfig.js脚本文件,将其设置为“嵌入的资源”。这个js文件的功能主要有两个:一个是汉化,另一个是在界面上显示控制器的描述文字。

代码如下:


  
  
  1. 'use strict';
  2. window.SwaggerTranslator = {
  3. _words: [],
  4. translate: function () {
  5. var $ this = this;
  6. $( '[data-sw-translate]').each( function () {
  7. $( this).html($ this._tryTranslate($( this).html()));
  8. $( this).val($ this._tryTranslate($( this).val()));
  9. $( this).attr( 'title', $ this._tryTranslate($( this).attr( 'title')));
  10. });
  11. },
  12. setControllerSummary: function () {
  13. $.ajax({
  14. type: "get",
  15. async: true,
  16. url: $( "#input_baseUrl").val(),
  17. dataType: "json",
  18. success: function (data) {
  19. var summaryDict = data.ControllerDesc;
  20. var id, controllerName, strSummary;
  21. $( "#resources_container .resource").each( function (i, item) {
  22. id = $(item).attr( "id");
  23. if (id) {
  24. controllerName = id.substring( 9);
  25. strSummary = summaryDict[controllerName];
  26. if (strSummary) {
  27. $(item).children( ".heading").children( ".options").first().prepend( '<li class="controller-summary" title="' + strSummary + '">' + strSummary + '</li>');
  28. }
  29. }
  30. });
  31. }
  32. });
  33. },
  34. _tryTranslate: function (word) {
  35. return this._words[$.trim(word)] !== undefined ? this._words[$.trim(word)] : word;
  36. },
  37. learn: function (wordsMap) {
  38. this._words = wordsMap;
  39. }
  40. };
  41. /* jshint quotmark: double */
  42. window.SwaggerTranslator.learn({
  43. "Warning: Deprecated": "警告:已过时",
  44. "Implementation Notes": "实现备注",
  45. "Response Class": "响应类",
  46. "Status": "状态",
  47. "Parameters": "参数",
  48. "Parameter": "参数",
  49. "Value": "值",
  50. "Description": "描述",
  51. "Parameter Type": "参数类型",
  52. "Data Type": "数据类型",
  53. "Response Messages": "响应消息",
  54. "HTTP Status Code": "HTTP状态码",
  55. "Reason": "原因",
  56. "Response Model": "响应模型",
  57. "Request URL": "请求URL",
  58. "Response Body": "响应体",
  59. "Response Code": "响应码",
  60. "Response Headers": "响应头",
  61. "Hide Response": "隐藏响应",
  62. "Headers": "头",
  63. "Try it out!": "试一下!",
  64. "Show/Hide": "显示/隐藏",
  65. "List Operations": "显示操作",
  66. "Expand Operations": "展开操作",
  67. "Raw": "原始",
  68. "can't parse JSON. Raw result": "无法解析JSON. 原始结果",
  69. "Model Schema": "模型架构",
  70. "Model": "模型",
  71. "apply": "应用",
  72. "Username": "用户名",
  73. "Password": "密码",
  74. "Terms of service": "服务条款",
  75. "Created by": "创建者",
  76. "See more at": "查看更多:",
  77. "Contact the developer": "联系开发者",
  78. "api version": "api版本",
  79. "Response Content Type": "响应Content Type",
  80. "fetching resource": "正在获取资源",
  81. "fetching resource list": "正在获取资源列表",
  82. "Explore": "浏览",
  83. "Show Swagger Petstore Example Apis": "显示 Swagger Petstore 示例 Apis",
  84. "Can't read from server. It may not have the appropriate access-control-origin settings.": "无法从服务器读取。可能没有正确设置access-control-origin。",
  85. "Please specify the protocol for": "请指定协议:",
  86. "Can't read swagger JSON from": "无法读取swagger JSON于",
  87. "Finished Loading Resource Information. Rendering Swagger UI": "已加载资源信息。正在渲染Swagger UI",
  88. "Unable to read api": "无法读取api",
  89. "from path": "从路径",
  90. "server returned": "服务器返回"
  91. });
  92. $( function () {
  93. window.SwaggerTranslator.translate();
  94. window.SwaggerTranslator.setControllerSummary();
  95. });

6、修改SwaggerConfig.cs

Swagger安装完毕后App_Start文件夹下才会有SwaggerConfig.cs文件,修改后的SwaggerConfig.cs的代码如下:

注意代码中 JiaHua.Permission.Api是项目名称,请改成自己项目对应的名称!


  
  
  1. public class SwaggerConfig
  2. {
  3. public static void Register()
  4. {
  5. var thisAssembly = typeof(SwaggerConfig).Assembly;
  6. GlobalConfiguration.Configuration
  7. .EnableSwagger(c =>
  8. {
  9. c.SingleApiVersion( "v1", "JiaHua.Permission.Api");
  10. //添加下述代码
  11. var xmlFile = string.Format( "{0}/bin/JiaHua.Permission.Api.XML", System.AppDomain.CurrentDomain.BaseDirectory);
  12. if (System.IO.File.Exists(xmlFile))
  13. {
  14. c.IncludeXmlComments(xmlFile);
  15. }
  16. c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
  17. c.CustomProvider((defaultProvider) => new SwaggerControllerDescProvider(defaultProvider, xmlFile));
  18. })
  19. .EnableSwaggerUi(b =>
  20. {
  21. b.InjectJavaScript(Assembly.GetExecutingAssembly(), "JiaHua.Permission.Api.Scripts.SwaggerConfig.js");
  22. });
  23. }
  24. }

7、修改项目的“XML文档文件”属性

右键项目--》属性--》生成

8、注释显示成功

9、小瑕疵及解决方法

                        <li class="tool-item tool-active is-like "><a href="javascript:;"><svg class="icon" aria-hidden="true">
                            <use xlink:href="#csdnc-thumbsup"></use>
                        </svg><span class="name">点赞</span>
                        <span class="count"></span>
                        </a></li>
                        <li class="tool-item tool-active is-collection "><a href="javascript:;" data-report-click="{&quot;mod&quot;:&quot;popu_824&quot;}"><svg class="icon" aria-hidden="true">
                            <use xlink:href="#icon-csdnc-Collection-G"></use>
                        </svg><span class="name">收藏</span></a></li>
                        <li class="tool-item tool-active is-share"><a href="javascript:;"><svg class="icon" aria-hidden="true">
                            <use xlink:href="#icon-csdnc-fenxiang"></use>
                        </svg>分享</a></li>
                        <!--打赏开始-->
                                                <!--打赏结束-->
                                                <li class="tool-item tool-more">
                            <a>
                            <svg t="1575545411852" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5717" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M179.176 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5718"></path><path d="M509.684 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5719"></path><path d="M846.175 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5720"></path></svg>
                            </a>
                            <ul class="more-box">
                                <li class="item"><a class="article-report">文章举报</a></li>
                            </ul>
                        </li>
                                            </ul>
                </div>
                                <div class="right-toolbox"><a href="https://blog.csdn.net/xiaouncle/article/details/83995809" target="_blank" class="jump-net-article">
                <svg t="1575545252354" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5597" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M243.9 1022.2c-62.3 0-124-23.8-171.5-70.8C26.4 905.5 1.5 845 1.5 779.9s24.9-125.6 70.8-171.5l184-184.1c45.9-45.9 106.4-70.8 171.5-70.8s125.6 24.9 171.5 70.8c18.1 18.1 18.1 47 0 65.1s-47 18.1-65.1 0c-28.3-28.3-65.7-43.5-105.9-43.5s-78.1 15.3-105.9 43.7l-184 184c-58.3 58.3-58.3 153.4 0 212.3 28.3 28.3 65.7 43.5 105.9 43.5s78.1-15.3 105.9-43.5l184-184c18.1-18.1 47-18.1 65.1 0 18.1 18.1 18.1 47 0 65.1l-184 184c-46.9 48-109.1 71.2-171.4 71.2z m523.7-423l184-184c94.5-94.5 94.5-248 0-342.5s-248-94.5-342.5 0l-184 184c-18.1 18.1-18.1 47 0 65.1s47 18.1 65.1 0l184-184c28.3-28.3 65.7-43.5 105.9-43.5s78.1 15.3 105.9 43.5c58.3 58.3 58.3 153.4 0 212.3l-184 184c-58.3 58.3-153.4 58.3-212.3 0-18.1-18.1-47-18.1-65.1 0-18.1 18.1-18.1 47 0 65.1 47 47 109.3 70.8 171.5 70.8s123.9-23.2 171.5-70.8z" p-id="5598"></path></svg>
                    站内首发文章</a></div>
                            </div>
            <div class="person-messagebox">
                <div class="left-message"><a href="https://blog.csdn.net/huan13479195089">
                    <img src="https://profile.csdnimg.cn/B/B/D/3_huan13479195089" class="avatar_pic" username="huan13479195089">
                                            <img src="https://g.csdnimg.cn/static/user-reg-year/2x/10.png" class="user-years">
                                    </a></div>
                <div class="middle-message">
                                        <div class="title"><span class="tit"><a href="https://blog.csdn.net/huan13479195089" data-report-click="{&quot;mod&quot;:&quot;popu_379&quot;}" target="_blank">sufengmarket</a></span>
                                            </div>
                    <div class="text"><span>发布了13 篇原创文章</span> · <span>获赞 1</span> · <span>访问量 4350</span></div>
                </div>
                                <div class="right-message">
                                            <a href="https://im.csdn.net/im/main.html?userName=huan13479195089" target="_blank" class="btn btn-sm btn-red-hollow bt-button personal-letter">私信
                        </a>
                                                            <a class="btn btn-sm attented bt-button personal-watch" data-report-click="{&quot;mod&quot;:&quot;popu_379&quot;}">已关注</a>
                                    </div>
                            </div>
                    </div>
    
发布了20 篇原创文章 · 获赞 0 · 访问量 770

WebApi接口开发完毕后,交付给前端人员或手机端开发者时接口说明文档是必不可少的配套设备,如果公司流程不规范大家使用口口相传的交接方式,而且没有改进的欲望,那你可以到此为止了。Swagger是方便测试接口,快速展示注释内容,生成Restful风格接口文档的框架。

猜你喜欢

转载自blog.csdn.net/weixin_44481764/article/details/104503075