using Swashbuckle.Swagger;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Xml;
namespace VueWebApi.App_Start
{
///
/// swagger显示控制器的描述
///
public class SwaggerControllerDescProvider : ISwaggerProvider
{
private readonly ISwaggerProvider _swaggerProvider;
private static ConcurrentDictionary _cache = new ConcurrentDictionary();
private readonly string _xml;
///
///
///
///
/// xml文档路径
public SwaggerControllerDescProvider(ISwaggerProvider swaggerProvider, string xml)
{
_swaggerProvider = swaggerProvider;
_xml = xml;
}
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 { { "ControllerDesc", GetControllerDesc() } };
_cache.TryAdd(cacheKey, srcDoc);
}
return srcDoc;
}
///
/// 从API文档中读取控制器描述
///
/// 所有控制器描述
public ConcurrentDictionary GetControllerDesc()
{
string xmlpath = _xml;
ConcurrentDictionary controllerDescDict = new ConcurrentDictionary();
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 = -1, 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 - 1];
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;
}
}
}