为swagger增加枚举说明支持
This commit is contained in:
parent
48c6d1299c
commit
baff3035e8
|
@ -12,20 +12,18 @@ namespace Falcon.SugarApi.ApiDefinistions
|
|||
/// </summary>
|
||||
public class ApiResponseTypeModelProvider : IApplicationModelProvider
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public int Order => 1;
|
||||
|
||||
public void OnProvidersExecuted(ApplicationModelProviderContext context)
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public void OnProvidersExecuted(ApplicationModelProviderContext context) {
|
||||
}
|
||||
|
||||
public void OnProvidersExecuting(ApplicationModelProviderContext context)
|
||||
{
|
||||
foreach (ControllerModel controller in context.Result.Controllers)
|
||||
{
|
||||
foreach (ActionModel action in controller.Actions)
|
||||
{
|
||||
if (!isApiAction(action))
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public void OnProvidersExecuting(ApplicationModelProviderContext context) {
|
||||
foreach (ControllerModel controller in context.Result.Controllers) {
|
||||
foreach (ActionModel action in controller.Actions) {
|
||||
if (!isApiAction(action)) {
|
||||
continue;
|
||||
}
|
||||
var art = action.ActionMethod.ReturnType;
|
||||
|
@ -43,14 +41,11 @@ namespace Falcon.SugarApi.ApiDefinistions
|
|||
/// </summary>
|
||||
/// <param name="am">Action模型</param>
|
||||
/// <returns>是api方法返回true,否则false</returns>
|
||||
protected static bool isApiAction(ActionModel am)
|
||||
{
|
||||
if (am.Controller.Attributes.Any(c => c is ApiControllerAttribute))
|
||||
{
|
||||
protected static bool isApiAction(ActionModel am) {
|
||||
if (am.Controller.Attributes.Any(c => c is ApiControllerAttribute)) {
|
||||
return true;
|
||||
}
|
||||
if (am.Attributes.Any(c => c is ApiControllerAttribute))
|
||||
{
|
||||
if (am.Attributes.Any(c => c is ApiControllerAttribute)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" />
|
||||
<PackageReference Include="SqlSugarCore" Version="5.0.6.1" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="5.6.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net5' ">
|
||||
|
|
19
Falcon.SugarApi/Swagger/Readme.md
Normal file
19
Falcon.SugarApi/Swagger/Readme.md
Normal file
|
@ -0,0 +1,19 @@
|
|||
## 使用SwaggerGenOptions.AddXmlEnumEnable方法可以为枚举类型增加matedata说明
|
||||
|
||||
```c#
|
||||
//注册Swagger
|
||||
services.AddSwaggerGen(c => {
|
||||
//获取应用程序基础目录
|
||||
var basePath = AppContext.BaseDirectory;
|
||||
//指定应用程序说明XML文件
|
||||
var xmlFile = new string[] { "ggws.Service.xml", "Ggws.Database.xml", "Falcon.SugarApi.xml" };
|
||||
foreach (var xf in xmlFile) {
|
||||
var path = Path.Combine(basePath, xf);
|
||||
//引入文件
|
||||
c.IncludeXmlComments(path, true);
|
||||
//为枚举增加说明
|
||||
c.AddXmlEnumEnable(path);
|
||||
}
|
||||
});
|
||||
|
||||
```
|
22
Falcon.SugarApi/Swagger/SwaggerGenOptionsExtend.cs
Normal file
22
Falcon.SugarApi/Swagger/SwaggerGenOptionsExtend.cs
Normal file
|
@ -0,0 +1,22 @@
|
|||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||
|
||||
namespace Falcon.SugarApi.Swagger
|
||||
{
|
||||
/// <summary>
|
||||
/// SwaggerGenOptions扩展
|
||||
/// </summary>
|
||||
public static class SwaggerGenOptionsExtend
|
||||
{
|
||||
/// <summary>
|
||||
/// 增加xml文件枚举说明支持
|
||||
/// </summary>
|
||||
/// <param name="options">SwaggerGenOptions选项</param>
|
||||
/// <param name="xmlPath">XML文件路径</param>
|
||||
/// <returns>SwaggerGenOptions</returns>
|
||||
public static SwaggerGenOptions AddXmlEnumEnable(this SwaggerGenOptions options,string xmlPath) {
|
||||
options.DocumentFilter<SwaggerXmlEnumFilter>(xmlPath);
|
||||
return options;
|
||||
}
|
||||
}
|
||||
}
|
93
Falcon.SugarApi/Swagger/SwaggerXmlEnumFilter.cs
Normal file
93
Falcon.SugarApi/Swagger/SwaggerXmlEnumFilter.cs
Normal file
|
@ -0,0 +1,93 @@
|
|||
using Microsoft.OpenApi.Any;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Xml.XPath;
|
||||
|
||||
namespace Falcon.SugarApi.Swagger
|
||||
{
|
||||
/// <summary>
|
||||
/// 通过DescriptionAttribute和summary生成枚举说明
|
||||
/// </summary>
|
||||
public class SwaggerXmlEnumFilter:IDocumentFilter
|
||||
{
|
||||
private readonly XPathNavigator _xmlNavigator;
|
||||
|
||||
/// <summary>
|
||||
/// 存放程序集中的所有枚举类型
|
||||
/// </summary>
|
||||
public static List<Type> AllTypes { get; set; } = null;
|
||||
|
||||
/// <summary>
|
||||
/// 通过提供应用程序文档生成枚举说明
|
||||
/// </summary>
|
||||
/// <param name="xmlPath"></param>
|
||||
public SwaggerXmlEnumFilter(string xmlPath) {
|
||||
_xmlNavigator = new XPathDocument(xmlPath).CreateNavigator();
|
||||
|
||||
AllTypes = AllTypes ?? GetEnumTypes();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化程序集中所有枚举类型
|
||||
/// </summary>
|
||||
public virtual List<Type> GetEnumTypes() {
|
||||
var types = new List<Type>();
|
||||
foreach(var ass in AppDomain.CurrentDomain.GetAssemblies()) {
|
||||
types.AddRange(ass.GetTypes().Where(m => m.IsEnum));
|
||||
}
|
||||
return types;
|
||||
}
|
||||
/// <summary>
|
||||
/// 对文档进行初拉力
|
||||
/// </summary>
|
||||
/// <param name="swaggerDoc"></param>
|
||||
/// <param name="context"></param>
|
||||
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<OpenApiInteger>();
|
||||
foreach(var val in property.Enum) {
|
||||
list.Add((OpenApiInteger)val);
|
||||
}
|
||||
property.Description += describeEnum(itemType,list);
|
||||
}
|
||||
}
|
||||
|
||||
private string describeEnum(Type type,List<OpenApiInteger> enums) {
|
||||
var enumDescriptions = new List<string>();
|
||||
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}:{Enum.GetName(type,value)}; ");
|
||||
else
|
||||
enumDescriptions.Add($"{item.Value}:{Enum.GetName(type,value)},{desc}; ");
|
||||
|
||||
}
|
||||
return $"<br/>{Environment.NewLine}{string.Join("<br/>" + 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<DescriptionAttribute>()) {
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -92,6 +92,10 @@ namespace Falcon.SugarApi.XmlSerialize
|
|||
#endregion
|
||||
#pragma warning restore CS1591 // 缺少对公共可见类型或成员的 XML 注释
|
||||
|
||||
/// <summary>
|
||||
/// 释放占用资源
|
||||
/// </summary>
|
||||
/// <param name="disposing"></param>
|
||||
protected override void Dispose(bool disposing) {
|
||||
if (disposing) {
|
||||
this.BaseWriter.Dispose();
|
||||
|
|
Loading…
Reference in New Issue
Block a user