• ASP.NET Swagger 创建与汉化生成 API说明文档


    ASP.NET Swagger 创建与汉化生成 API说明文档

    本篇文章将以ASP.NET Web Api 示例:

    1.首先引入下面两个NuGet包

     

     

    2.安装完成后App_Start文件夹下出现SwaggerConfig.cs和SwaggerNet.cs

     

     3.打开SwaggerNet.cs文件,注释下面的代码:

    [assembly: WebActivator.PreApplicationStartMethod(typeof(WebApi.App_Start.SwaggerNet), "PreStart")]
    [assembly: WebActivator.PostApplicationStartMethod(typeof(WebApi.App_Start.SwaggerNet), "PostStart")]

     4.右键项目属性,在Web选项中,启动操作勾选特定页,输入swagger/ui/index#/   当然这不是必须的

        在项目属性的生成项中勾选输出XML文档

     

     

     5.在App_Start文件夹下创建SwaggerCacheProvider.cs

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

     

    6.配置SwaggerConfig.cs   //注下面代码已对Swagger默认接口做了隐藏 

     1 using System.Web.Http;
     2 using WebActivatorEx;
     3 using WebApi;
     4 using Swashbuckle.Application;
     5 using System;
     6 using Swashbuckle.Swagger;
     7 using System.Web.Http.Description;
     8 using System.Linq;
     9 using WebApi.App_Start;
    10 
    11 [assembly: PreApplicationStartMethod(typeof(SwaggerConfig), "Register")]
    12 
    13 namespace WebApi
    14 {
    15     /// <summary>
    16     /// 配置SwaggerConfig
    17     /// </summary>
    18     public class SwaggerConfig
    19     {
    20         /// <summary>
    21         /// Register
    22         /// </summary>
    23         public static void Register()
    24         {
    25             var thisAssembly = typeof(SwaggerConfig).Assembly;
    26 
    27             GlobalConfiguration.Configuration
    28                 .EnableSwagger(c =>
    29                 {
    30                     c.SingleApiVersion("v1", "WebApi User Guide");
    31                     c.IncludeXmlComments(GetXmlCommentsPath(GetXmlCommentsPath(thisAssembly.GetName().Name)));
    32                     c.CustomProvider((defaultProvider) => new SwaggerCacheProvider(defaultProvider, string.Format(@"{0}inWebApi.XML", System.AppDomain.CurrentDomain.BaseDirectory)));
    33                     c.DocumentFilter<HiddenApiFilter>();//隐藏Swagger 自带API及隐藏具体Api
    34                 })
    35                 .EnableSwaggerUi(c =>
    36                 {
    37                     c.InjectJavaScript(System.Reflection.Assembly.GetExecutingAssembly(), "WebApi.scripts.swagger.js");
    38                 });
    39         }
    40         /// <summary>
    41         /// 获取接口的注释
    42         /// </summary>
    43         /// <param name="name"></param>
    44         /// <returns></returns>
    45         protected static string GetXmlCommentsPath(string name)
    46         {
    47             return string.Format(@"{0}inWebApi.XML", AppDomain.CurrentDomain.BaseDirectory, name);
    48         }
    49     }
    50 }
    51 /// <summary>
    52 /// 隐藏Swagger默认接口
    53 /// </summary>
    54 [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
    55 public partial class HiddenApiAttribute : Attribute { }
    56 /// <summary>
    57 /// 隐藏Swagger默认接口
    58 /// </summary>
    59 public class HiddenApiFilter : IDocumentFilter
    60 {
    61     public void Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, IApiExplorer apiExplorer)
    62     {
    63         foreach (ApiDescription apiDescription in apiExplorer.ApiDescriptions)
    64         {
    65             var _key = "/" + apiDescription.RelativePath.TrimEnd('/');
    66             // 过滤 swagger 自带的接口
    67             if (_key.Contains("/api/Swagger") && swaggerDoc.paths.ContainsKey(_key))
    68                 swaggerDoc.paths.Remove(_key);
    69 
    70             //隐藏具体Api接口 需要在想隐藏的api 上面添加特性[HiddenApi]
    71             if (Enumerable.OfType<HiddenApiAttribute>(apiDescription.GetControllerAndActionAttributes<HiddenApiAttribute>()).Any())
    72             {
    73                 string key = "/" + apiDescription.RelativePath;
    74                 if (key.Contains("?"))
    75                 {
    76                     int idx = key.IndexOf("?", System.StringComparison.Ordinal);
    77                     key = key.Substring(0, idx);
    78                 }
    79                 swaggerDoc.paths.Remove(key);
    80             }
    81         }
    82     }
    83 }

    7.创建js文件把下面代码拷贝进去保存即可 并做嵌入的资源 js代码如下: //这一步是为了汉化使用

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

     8.因对swagger默认接口做了隐藏所以我们要自己写一下  //我就随便写了一下 具体需求你们自己定义

     

     9.效果如图所示:

    swagger文档非常适用于前后端分离 

    如需转载请注明出处

  • 相关阅读:
    测试开发面试集锦_数据库
    测试开发面试集锦_linux
    测试开发面试题集锦_java
    Java中equals 和==的区别
    定时清理文件shell脚本
    java文件上传,upload使用
    python 获取错误日志,并发送邮件
    c语言代码审计规范
    渗透测试之nmap
    渗透测试之GoogleHack
  • 原文地址:https://www.cnblogs.com/exyz/p/11449591.html
Copyright © 2020-2023  润新知