2020-06-04

在MVC项目中使用 Swagger API文档

在MVC项目中使用 Swagger API文档


参考文档:

https://www.cnblogs.com/liaods/p/10101513.html

https://www.cnblogs.com/zyz-Notes/p/12030281.html

 

本示例使用MVC项目做演示(不推荐,推荐直接用WebAPI),框架版本使用 4.6.2 

为了支持WebAPI,我们需要把当前的MVC项目改造一下,右键项目,通过 Nuget添加WebAPI的支持

 

在 App_Start 文件夹下添加 WebApiConfig 类

 1  public class WebApiConfig 2  { 3   public static void Register(HttpConfiguration config) 4   { 5    // Web API 配置和服务 7    // Web API 路由 8    config.MapHttpAttributeRoutes(); 9 10    config.Routes.MapHttpRoute(11     name: "DefaultApi",12     routeTemplate: "api/{controller}/{action}/{id}",13     defaults: new { id = RouteParameter.Optional }14    );17    var jsonFormatter = new JsonMediaTypeFormatter();20    //jsonFormatter.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;23   }24  }

然后在全局中注册改文件,代码放到第二行,接下来就可以使用了

右键项目安装: Swashbuckle   版本 5.6.0

 

安装成功之后,在App_Start文件夹下多了一个文件:SwaggerConfig.cs

 

 打开全局视图 _Layout.cshtml,在里边添加一个链接:

<li>@Html.ActionLink("Swagger Help", "", "Swagger", new { area = "" }, null)</li>

直接运行,效果如下:

添加一个测试接口,UserInfoController

 1  public class UserInfoController : BaseController 2  { 3   /// <summary> 4   /// GET: 用户信息首页接口 5   /// </summary> 6   /// <remarks> 7   /// 我是备注信息 8   /// </remarks> 9   /// <returns>我是返回信息</returns>10   [HttpGet]11   public IHttpActionResult Index()12   {13    return Json("Hello World");14   }15  }

如下图所示,接口显示出来了,但都是英文,备注信息也没有显示出来,后边解决

 

 点击按钮: “Try It out”,会返回该接口内容

接下来,我们解决备注不显示的问题,项目右键-->属性,在 生成 选项卡中勾选

然后打开 SwaggerConfig.cs 类,找到函数: c.Include

并添加方法:Get

  /// <summary>  /// 获取文档路径  /// </summary>  /// <returns></returns>  static string Getreturn $@"{System.AppDomain.CurrentDomain.BaseDirectory}\bin\Swagger.Mvc.";  }

现在注释信息显示出来了,但是其他的地方还是英文

 添加汉化支持,添加自定义汉化脚本,右键项目,添加文件夹 Swagger,添加js脚本文件 swagger_lang.js,右键该脚本文件,在属性中的生成操作改为嵌入的资源

 

复制如下脚本:

///<summary>/// 中文转换///</summary>var SwaggerTranslator = (function () { //定时执行检测是否转换成中文,最多执行500次 即500*50/1000=25s var iexcute = 0,  //中文语言包  _words = {   "Warning: Deprecated": "警告:已过时",   "Implementation Notes": "实现备注",   "Response Class": "响应类",   "Status": "状态",   "Parameters": "参数",   "Parameter": "参数",   "Value": "值",   "Description": "描述",   "Parameter Type": "参数类型",   "Data Type": "数据类型",   "Response Messages": "响应消息",   "HTTP Status Code": "HTTP状态码",   "Reason": "原因",   "Response Model": "响应模型",   "Request URL": "请求URL",   "Response Body": "响应体",   "Response Code": "响应码",   "Response Headers": "响应头",   "Hide Response": "隐藏响应",   "Headers": "头",   "Try it out!": "试一下!",   "Show/Hide": "显示/隐藏",   "List Operations": "显示操作",   "Expand Operations": "展开操作",   "Raw": "原始",   "can't parse JSON. Raw result": "无法解析JSON. 原始结果",   "Model Schema": "模型架构",   "Model": "模型",   "apply": "应用",   "Username": "用户名",   "Password": "密码",   "Terms of service": "服务条款",   "Created by": "创建者",   "See more at": "查看更多:",   "Contact the developer": "联系开发者",   "api version": "api版本",   "Response Content Type": "响应Content Type",   "fetching resource": "正在获取资源",   "fetching resource list": "正在获取资源列表",   "Explore": "浏览",   "Show Swagger Petstore Example Apis": "显示 Swagger Petstore 示例 Apis",   "Can't read from server. It may not have the appropriate access-control-origin settings.": "无法从服务器读取。可能没有正确设置access-control-origin。",   "Please specify the protocol for": "请指定协议:",   "Can't read swagger JSON from": "无法读取swagger JSON于",   "Finished Loading Resource Information. Rendering Swagger UI": "已加载资源信息。正在渲染Swagger UI",   "Unable to read api": "无法读取api",   "from path": "从路径",   "Click to set as parameter value": "点击设置参数",   "server returned": "服务器返回"  },  //定时执行转换  _translator2Cn = function () {   if ($("#resources_container .resource").length > 0) {    _tryTranslate();   }   if ($("#explore").text() == "Explore" && iexcute < 500) {    iexcute++;    setTimeout(_translator2Cn, 50);   }  },  //设置控制器注释  _setControllerSummary = function () {   $.ajax({    type: "get",    async: true,    url: $("#input_baseUrl").val(),    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(9);       strSummary = summaryDict[controllerName];       if (strSummary) {        $(item).children(".heading").children(".options").prepend('<li title="' + strSummary + '">' + strSummary + '</li>');       }      }     });    }   });  },  //尝试将英文转换成中文  _tryTranslate = function () {   $('[data-sw-translate]').each(function () {    $(this).html(_getLangDesc($(this).html()));    $(this).val(_getLangDesc($(this).val()));    $(this).attr('title', _getLangDesc($(this).attr('title')));   });  },  _getLangDesc = function (word) {   return _words[$.trim(word)] !== undefined ? _words[$.trim(word)] : word;  }; return {  Translator: function () {   document.title = "API描述文档";   $('body').append('<style type="text/css">.controller-summary{color:#10a54a !important;word-break:keep-all;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:250px;text-align:right;cursor:default;} </style>');   $("#logo").html("接口描述").attr("href", "/Home/Index");   //设置控制器描述   _setControllerSummary();   _translator2Cn();  } }})();//执行转换SwaggerTranslator.Translator();

打开 SwaggerConfig.cs 类 ,找到函数:InjectJavaScript,并修改成上边自定义的js文件路径,格式用点分开

c.InjectJavaScript(thisAssembly, "Swagger.Mvc.Swagger.swagger_lang.js");

添加控制器描述和接口文档缓存

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

在SwaggerConfig.cs 类 中放开注释代码:

c.CustomProvider((defaultProvider) => new CachingSwaggerProvider(defaultProvider));

再次运行程序后,现在变成中的了。

备注内容换行,在相应备注后边加 <br></br>即可出现换行,换行标签要成对出现,否则会报错

 

最后运行效果如下:

 

 

 

 

 

总结:

最后有个问题,就是项目名称中间不能用点来分割,比如: Swagger.Mvc 这样就不行,这样的名字,上边汉化时会找不到路径。所以需要把中间的点去掉,坑啊!


No comments:

Post a Comment