“五一”期間用了一下Swagger,碰到了以下問題: 如何在Docker中顯示OpenApiInfo的中文內容; 如何顯示xml註釋; 如何顯示Header; 如何隱藏ApiController、Action、類或者屬性,如何顯示枚舉 現將解決辦法記下留存。 一、在Docker中顯示OpenApiI ...
“五一”期間用了一下Swagger,碰到了以下問題:
- 如何在Docker中顯示OpenApiInfo的中文內容;
- 如何顯示xml註釋;
- 如何顯示Header;
- 如何隱藏ApiController、Action、類或者屬性,如何顯示枚舉
現將解決辦法記下留存。
一、在Docker中顯示OpenApiInfo的中文內容
builder.Services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1", new OpenApiInfo
{
Version = "v1",
Title = "xxx Api調用說明",
Description = "巴拉巴拉的一堆描述",
License = new OpenApiLicense
{
Name = "Api調用須知",
Url = new Uri("http://xxx.com/readmi.html")
}
});
});
以上設置的效果
然而發佈到Docker以後,中文亂碼了(似乎在Program.cs裡面輸入的中文都會亂碼)。我的解決的辦法是:
builder.Services.AddSwaggerGen(ProgramHelper.SwaggerSetup);
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
namespace SwaggerDemo;
public static class ProgramHelper
{
public static void SwaggerSetup(SwaggerGenOptions options)
{
options.SwaggerDoc("v1", new OpenApiInfo
{
Version = "v1",
Title = "xxx Api調用說明",
Description = "巴拉巴拉的一堆描述",
License = new OpenApiLicense
{
Name = "Api調用須知",
Url = new Uri("http://xxx.com/readmi.html")
}
});
}
}
問題解決,但有點脫褲子放屁,不知道有沒有不需要脫褲子的方法。
二、顯示xml註釋
三、如何顯示Header
辦法如下:
public class SwaggerHeaderAttribute : Attribute { }
public class SwaggerOperationFilter : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
if (context.ApiDescription.CustomAttributes().Any(ii => ii.GetType() == typeof(SwaggerHeaderAttribute))
|| context.ApiDescription.ActionDescriptor.EndpointMetadata.Any(ii => ii.GetType() == typeof(SwaggerHeaderAttribute)))
{
if (operation.Parameters == null)
operation.Parameters = new List<OpenApiParameter>();
operation.Parameters.Add(new OpenApiParameter
{
Name = "Sign",
In = ParameterLocation.Header,
Description = "我的簽名是這個生成的,巴拉巴拉巴拉",
Required = true
});
}
}
}
然後在SwaggerSetup裡面添加一行
options.OperationFilter<SwaggerOperationFilter>();
在ApiController或者Action前面添加一行[SwaggerHeader]
四、隱藏ApiController、Action、類或者屬性,顯示枚舉
想把1、2隱藏起來,把
public enum ECode
{
成功,
[Description("時間戳錯誤")]
Timestamp,
[Description("簽名錯誤")]
Sign
}
顯示成3的樣子,辦法如下:
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Enum | AttributeTargets.Field)]
public partial class SwaggerIgnoreAttribute : Attribute { }
public class SwaggerSchemaFilter : ISchemaFilter
{
public void Apply(OpenApiSchema schema, SchemaFilterContext context)
{
#region 給設置了SwaggerIgnoreAttribute特性的類作個標記,以便在DocumentFilter裡面移除整個架構
if (context.Type.GetCustomAttribute<SwaggerIgnoreAttribute>() != null)
{
schema.Title = "Remove";
}
#endregion
else
{
if (context.Type.IsEnum)
{
#region 設置枚舉的描述
List<string> titleItems = new List<string>();
foreach (var e in Enum.GetValues(context.Type))
{
if (context.Type.GetField(e.ToString()).GetCustomAttribute<SwaggerIgnoreAttribute>() == null)
{
titleItems.Add($"{(int)e}:{context.Type.GetField(e.ToString()).GetCustomAttribute<DescriptionAttribute>()?.Description ?? e}");
}
}
schema.Description = string.Join(";", titleItems);
#endregion
}
else
{
#region 移除設置了SwaggerIgnoreAttribute特性的屬性
foreach (var propertyName in context.Type.GetProperties().Where(ii => ii.GetCustomAttribute<SwaggerIgnoreAttribute>() != null).Select(ii => ii.Name))
schema.Properties.Remove(propertyName);
#region
}
}
}
}
public class SwaggerDocFilter : IDocumentFilter
{
public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
{
//移除在SchemaFilter作了標記的架構
foreach (var key in swaggerDoc.Components.Schemas.Where(ii => ii.Value.Title == "Remove"))
swaggerDoc.Components.Schemas.Remove(key);
#region 移除設置了SwaggerIgnoreAttribute特性的ApiController
var ignoreApis = context.ApiDescriptions.Where(wh => wh.ActionDescriptor.EndpointMetadata.Any(any => any is SwaggerIgnoreAttribute));
if (ignoreApis != null)
{
foreach (var ignoreApi in ignoreApis)
{
swaggerDoc.Paths.Remove("/" + ignoreApi.RelativePath);
}
}
#endregion
}
}
照例需要在在SwaggerSetup裡面添加兩行
options.SchemaFilter<SwaggerSchemaFilter>();
options.DocumentFilter<SwaggerDocFilter>();
然後給隱藏的內容添加[SwaggerIgnore]
如此,大致達到了我的目的,但存兩點不爽:
- 脫褲子
- 隱藏類的方式
若有答案,煩請告知,先謝!