Files
caliverse_server/BrokerApiServer/Common/SwaggerSettingHelper.cs
2025-05-01 07:23:28 +09:00

141 lines
4.3 KiB
C#

using System.Reflection;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
namespace BrokerApiServer;
using Microsoft.OpenApi.Any;
// 사용자 정의 스키마 필터 예시: Enum을 문자열로 표현
public class EnumAsStringSchemaFilter : ISchemaFilter
{
public void Apply(OpenApiSchema schema, SchemaFilterContext context)
{
if (context.Type.IsEnum)
{
schema.Type = "string";
schema.Enum = Enum.GetNames(context.Type)
.Select(name => new OpenApiString(name))
.Cast<IOpenApiAny>()
.ToList();
}
}
}
[AttributeUsage(AttributeTargets.Method)]
public class SwaggerRequestBodyWithSchemaAttribute : Attribute
{
public string Description { get; }
public Type Type { get; }
public SwaggerRequestBodyWithSchemaAttribute(string description, Type type)
{
Description = description;
Type = type;
}
}
public class SwaggerRequestBodyWithSchemaFilter : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
var methodInfo = context.MethodInfo;
// 커스텀 특성 가져오기
if (methodInfo.GetCustomAttributes(typeof(SwaggerRequestBodyWithSchemaAttribute), false)
.FirstOrDefault() is SwaggerRequestBodyWithSchemaAttribute attribute)
{
// 스키마 생성
var schema = context.SchemaGenerator.GenerateSchema(attribute.Type, context.SchemaRepository);
// 스키마 정보를 문자열로 변환
var schema_description = getSchemaDescription(schema);
// 기존 Description과 병합
var description = $"{attribute.Description}\n\n**스키마 정보:**\n{schema_description}";
if (operation.RequestBody != null)
{
operation.RequestBody.Description = description;
}
else
{
// RequestBody가 없을 경우 새로 생성
operation.RequestBody = new OpenApiRequestBody
{
Description = description,
Required = true,
Content = new Dictionary<string, OpenApiMediaType>
{
["application/json"] = new OpenApiMediaType
{
Schema = schema
}
}
};
}
}
}
private string getSchemaDescription(OpenApiSchema schema)
{
if (schema.Properties != null && schema.Properties.Any())
{
return string.Join("\n", schema.Properties.Select(prop =>
{
var prop_schema = prop.Value;
var type = prop_schema.Type ?? "object";
var format = !string.IsNullOrEmpty(prop_schema.Format) ? $" ({prop_schema.Format})" : "";
var description = !string.IsNullOrEmpty(prop_schema.Description) ? $": {prop_schema.Description}" : "";
return $"- **{prop.Key}** ({type}{format}){description}";
}));
}
else
{
return "스키마에 정의된 프로퍼티가 없습니다.";
}
}
}
public class SwaggerSettingHelper
{
public static void setSwaggerGen(SwaggerGenOptions genOptions)
{
genOptions.SwaggerDoc("v1", new OpenApiInfo { Title = "Metaverse Broker Api", Version = "v1" });
var xml_file = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xml_path = Path.Combine(AppContext.BaseDirectory, xml_file);
genOptions.IncludeXmlComments(xml_path);
genOptions.EnableAnnotations();
genOptions.SchemaFilter<EnumAsStringSchemaFilter>();
genOptions.OperationFilter<SwaggerRequestBodyWithSchemaFilter>();
genOptions.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
Name = "Authorization",
Type = SecuritySchemeType.Http,
Scheme = "Bearer",
BearerFormat = "JWT",
In = ParameterLocation.Header,
Description = "JWT Authorization header using the Bearer scheme."
});
genOptions.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
}
},
new string [] {}
}
});
}
}