.NET 8中Swashbuckle手动生成OpenApiSchema为空的问题
在Swashbuckle.AspNetCore 6.6.2中自定义IOperationFilter生成空Schema的解决方法
问题背景
在.NET 8服务中使用Swashbuckle.AspNetCore.Swagger 6.6.2,通过自定义IOperationFilter生成API请求示例时,调用ISchemaGenerator.GenerateSchema为未收录的POCO类型生成Schema,结果始终为空(无属性填充)。目标类型为公开可访问的POCO类,且已确认modelType指向正确,但生成的OAS JSON中该类型的Schema仅包含空对象。
解决方法
1. 使用带SchemaGeneratorOptions的重载方法
默认的GenerateSchema(Type, SchemaRepository)重载可能未应用正确的配置规则(如未启用属性扫描),需传入SchemaGeneratorOptions确保生成完整的Schema结构。
实现代码
public class MyCustomOperationFilter : IOperationFilter { private readonly SchemaGeneratorOptions _schemaGeneratorOptions; // 注入Swagger配置的Schema生成选项 public MyCustomOperationFilter(SchemaGeneratorOptions schemaGeneratorOptions) { _schemaGeneratorOptions = schemaGeneratorOptions; } public void Apply(OpenApiOperation operation, OperationFilterContext context) { // 替换为实际获取目标类型的逻辑 var modelType = typeof(MyClassExample); var schema = GenerateSpecializedSchema(modelType, context.SchemaRepository, context.SchemaGenerator); // 可将生成的Schema用于设置请求示例等操作 // 示例:operation.RequestBody = new OpenApiRequestBody { ... }; } private OpenApiSchema GenerateSpecializedSchema(Type modelType, SchemaRepository schemaRepository, ISchemaGenerator schemaGenerator) { // 优先使用仓库中已存在的Schema if (schemaRepository.TryGetSchema(modelType, out var existingSchema)) { return existingSchema; } // 使用带配置选项的重载生成Schema var schema = schemaGenerator.GenerateSchema(modelType, schemaRepository, _schemaGeneratorOptions); return schema; } }
注册过滤器
在Program.cs中添加注册逻辑:
builder.Services.AddSwaggerGen(c => { c.OperationFilter<MyCustomOperationFilter>(); });
2. 手动兜底生成属性
如果自动生成仍返回空Schema,可通过反射手动遍历类型属性并生成对应Schema,再添加到SchemaRepository中:
private OpenApiSchema GenerateSpecializedSchema(Type modelType, SchemaRepository schemaRepository, ISchemaGenerator schemaGenerator) { if (schemaRepository.TryGetSchema(modelType, out var existingSchema)) { return existingSchema; } var schema = schemaGenerator.GenerateSchema(modelType, schemaRepository, _schemaGeneratorOptions); // 兜底逻辑:自动生成失败时手动构建Schema if (schema.Properties == null || schema.Properties.Count == 0) { schema.Type = "object"; schema.Properties = new Dictionary<string, OpenApiSchema>(); foreach (var prop in modelType.GetProperties(BindingFlags.Public | BindingFlags.Instance)) { var propSchema = schemaGenerator.GenerateSchema(prop.PropertyType, schemaRepository, _schemaGeneratorOptions); schema.Properties.Add(prop.Name, propSchema); } // 将手动生成的Schema添加到仓库,避免重复处理 schemaRepository.AddDefinition(modelType.Name, schema); } return schema; }
3. 手动映射类型(可选兜底方案)
若上述方法均无效,可直接在Swagger配置中手动映射目标类型的Schema:
builder.Services.AddSwaggerGen(c => { c.MapType<MyClassExample>(() => new OpenApiSchema { Type = "object", Properties = new Dictionary<string, OpenApiSchema> { { "PropertyA", new OpenApiSchema { Type = "string", Example = new OpenApiString("示例值A") } }, { "PropertyB", new OpenApiSchema { Type = "string", Example = new OpenApiString("示例值B") } } } }); });
内容的提问来源于stack exchange,提问作者DanielK14
相关产品推荐
相关产品推荐

