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 FAuth.Extensions { /// /// 通过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; } } }