141 lines
4.3 KiB
C#
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 [] {}
|
|
}
|
|
});
|
|
}
|
|
}
|