From 30a34a7dee6dfbfe4855ee5e2878614172f13dda Mon Sep 17 00:00:00 2001 From: falcon <9504402@qq.com> Date: Wed, 1 Apr 2020 11:07:21 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0Swagger=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E6=9E=9A=E4=B8=BE=E8=AF=B4=E6=98=8E=E7=9A=84=E6=89=A9=E5=B1=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Falcon.Extend/Falcon.Extend.csproj | 4 ++ Falcon.Extend/SwaggerXmlEnumFilter.cs | 80 +++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 Falcon.Extend/SwaggerXmlEnumFilter.cs diff --git a/Falcon.Extend/Falcon.Extend.csproj b/Falcon.Extend/Falcon.Extend.csproj index 06090c4..60c7a0b 100644 --- a/Falcon.Extend/Falcon.Extend.csproj +++ b/Falcon.Extend/Falcon.Extend.csproj @@ -11,4 +11,8 @@ Falcon + + + + diff --git a/Falcon.Extend/SwaggerXmlEnumFilter.cs b/Falcon.Extend/SwaggerXmlEnumFilter.cs new file mode 100644 index 0000000..3bb0e46 --- /dev/null +++ b/Falcon.Extend/SwaggerXmlEnumFilter.cs @@ -0,0 +1,80 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Reflection; +using System.Xml.XPath; +using Microsoft.OpenApi.Any; +using Microsoft.OpenApi.Models; +using Swashbuckle.AspNetCore.SwaggerGen; + +namespace Falcon.Extend +{ + /// + /// 通过DescriptionAttribute和summary生成枚举说明 + /// + public class SwaggerXmlEnumFilter:IDocumentFilter + { + private readonly XPathNavigator _xmlNavigator; + + public static List AllTypes { get; set; } + + /// + /// 通过提供应用程序文档生成枚举说明 + /// + /// + public SwaggerXmlEnumFilter(string xmlPath) { + _xmlNavigator = new XPathDocument(xmlPath).CreateNavigator(); + + if(AllTypes == null) { + AllTypes = new List(); + foreach(var ass in AppDomain.CurrentDomain.GetAssemblies()) { + AllTypes.AddRange(ass.GetTypes().Where(m => m.IsEnum)); + } + } + } + + public void Apply(OpenApiDocument swaggerDoc,DocumentFilterContext context) { + var enumList = swaggerDoc.Components.Schemas.Where(m => m.Value.Enum != null && m.Value.Enum.Count > 0); + foreach(var item in enumList) { + var key = item.Key; + var property = item.Value; + var itemType = AllTypes.Find(m => m.Name == key); + var list = new List(); + foreach(var val in property.Enum) { + list.Add((OpenApiInteger)val); + } + property.Description += describeEnum(itemType,list); + } + } + + private string describeEnum(Type type,List enums) { + var enumDescriptions = new List(); + foreach(var item in enums) { + if(type == null) + continue; + var value = Enum.Parse(type,item.Value.ToString()); + var desc = getDescription(type,value); + + if(string.IsNullOrEmpty(desc)) + enumDescriptions.Add($"{item.Value.ToString()}:{Enum.GetName(type,value)}; "); + else + enumDescriptions.Add($"{item.Value.ToString()}:{Enum.GetName(type,value)},{desc}; "); + + } + return $"
{Environment.NewLine}{string.Join("
" + Environment.NewLine,enumDescriptions)}"; + } + + private string getDescription(Type t,object value) { + foreach(var member in t.GetMembers().Where(m => m.Name == t.GetEnumName(value))) { + foreach(var attr in member.GetCustomAttributes()) { + return attr.Description; + } + } + var fullName = $"{t.FullName}.{t.GetEnumName(value)}"; + var desc = _xmlNavigator.SelectSingleNode($"doc/members/member[@name='F:{fullName}']/summary")?.InnerXml; + return desc ?? string.Empty; + } + + } +}