using System.Collections.Concurrent;
using System.Xml;
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Interfaces;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.Swagger;
using VberZero;
using VberZero.Tools.StringModel;
namespace VberAdmin.Swagger
{
///
/// swagger显示控制器的描述
///
public class SwaggerControllerDescProvider : ISwaggerProvider
{
private readonly ISwaggerProvider _swaggerProvider;
private static readonly ConcurrentDictionary _cache = new ConcurrentDictionary();
private readonly string _xml;
///
///
///
///
/// xml文档路径
public SwaggerControllerDescProvider(ISwaggerProvider swaggerProvider, string xml)
{
_swaggerProvider = swaggerProvider;
_xml = xml;
}
public OpenApiDocument GetSwagger(string documentName, string host = null, string basePath = null)
{
var cacheKey = $"{documentName}";
//只读取一次
if (!_cache.TryGetValue(cacheKey, out var srcDoc))
{
srcDoc = _swaggerProvider.GetSwagger(documentName, host, basePath);
srcDoc.ExternalDocs = GetControllerDoc();
_cache.TryAdd(cacheKey, srcDoc);
}
return srcDoc;
}
public OpenApiExternalDocs GetControllerDoc()
{
string xmlPath = _xml;
ConcurrentDictionary controllerDescDict = new ConcurrentDictionary();
if (File.Exists(xmlPath))
{
XmlDocument xDoc = new XmlDocument();
xDoc.Load(xmlPath);
// ReSharper disable once PossibleNullReferenceException
foreach (XmlNode node in xDoc.SelectNodes("//member"))
{
if (node.Attributes != null)
{
var type = node.Attributes["name"]?.Value;
if (type != null && type.StartsWith("T:"))
{
//控制器
var arrPath = type.Split('.');
var length = arrPath.Length;
var controllerName = arrPath[length - 1];
string key = "";
var summaryNode = node.SelectSingleNode("summary");
if (controllerName.EndsWith("Controller"))
{
//获取控制器注释
int cCount = "Controller".Length;
key = controllerName.Remove(controllerName.Length - cCount, cCount);
}
else if (controllerName.EndsWith("AppService"))
{
//获取AppService注释
int cCount = "AppService".Length;
key = controllerName.Remove(controllerName.Length - cCount, cCount);
}
else if (controllerName.EndsWith("ApplicationService"))
{
//获取ApplicationService注释
int cCount = "ApplicationService".Length;
key = controllerName.Remove(controllerName.Length - cCount, cCount);
}
if (key.NotEmpty())
{
key = $"{VzConsts.AppApiName}95{key.Substring(0, 1).ToLowerInvariant() + key.Substring(1)}";
if (summaryNode != null && !string.IsNullOrEmpty(summaryNode.InnerText) && !controllerDescDict.ContainsKey(key))
{
controllerDescDict.TryAdd(key, new OpenApiString(summaryNode.InnerText.Trim()));
}
}
}
}
}
}
var doc = new OpenApiExternalDocs()
{
Extensions = controllerDescDict
};
return doc;
}
}
}