You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

经GenerateSchema添加的类在Swagger UI显示但未写入swagger.json

问题背景
  • 项目基于ASP.NET Core C#开发,包含控制器与Web API方法,集成Swagger实现接口测试、输出swagger.json文件,前端所需的类型定义通过NSwag Studio基于该swagger.json自动生成。
  • 需求为向swagger.json中显式添加一批未被任何Web API端点引用的类定义,这些类是项目通过SignalR发送给前端使用的业务类型。
  • 现有实现通过自定义IDocumentFilter,在过滤器中调用context.SchemaGenerator.GenerateSchema()方法添加额外类型,操作后这些类可在Swagger UI(访问地址https://localhost:7103/swagger/index.html)正常展示,但不会出现在最终生成的swagger.json文件中;更换为RegisterType()方法尝试后结果完全一致。
  • 现有核心实现代码如下:
// 服务注册阶段
services.AddSwaggerGen(options =>
{
    // 其他Swagger配置...
    options.DocumentFilter<AdditionalSchemasDocumentFilter>();
    // 其他Swagger配置...
});

// 自定义文档过滤器
public class AdditionalSchemasDocumentFilter : IDocumentFilter
{
    public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
    {
        // 现有添加schema的逻辑
        context.SchemaGenerator.GenerateSchema(typeof(Notification), context.SchemaRepository);
    }
}

// 中间件配置阶段
app.UseSwagger();
app.UseSwaggerUI(c =>
{
    c.SwaggerEndpoint($"/swagger/v1/swagger.json", "BackOffice API");
    // 其他UI配置...
});
问题原因

直接调用GenerateSchema或RegisterType方法,只会将生成的schema存入SchemaRepository的内部缓存,不会自动挂载到当前OpenApiDocument对象的Components.Schemas集合下。SwaggerUI运行时会直接读取SchemaRepository的全量缓存做渲染,因此可以看到新增的类型;但输出swagger.json时,序列化器只会序列化OpenApiDocument对象自身挂载的内容,未挂载到Components.Schemas的schema不会被写入最终的json文件。

可行解决方案

修改自定义AdditionalSchemasDocumentFilter的实现逻辑,生成schema后显式将其挂载到文档的Components.Schemas集合中,同时补全所有依赖的嵌套类型,参考实现如下:

public class AdditionalSchemasDocumentFilter : IDocumentFilter
{
    // 配置所有需要额外加入swagger.json的顶层SignalR类型
    private readonly Type[] _extraSignalRTypes = new Type[]
    {
        typeof(Notification),
        // 在此处追加其他需要暴露的类型,例如typeof(ChatMessage), typeof(SystemAlert)等
    };

    public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
    {
        // 先生成所有顶层类型的schema,生成过程会自动递归生成所有依赖的嵌套类型
        foreach (var type in _extraSignalRTypes)
        {
            context.SchemaGenerator.GenerateSchema(type, context.SchemaRepository);
        }

        // 将SchemaRepository中所有未挂载到文档的schema全量加入Components.Schemas
        foreach (var (schemaId, schema) in context.SchemaRepository.Schemas)
        {
            if (!swaggerDoc.Components.Schemas.ContainsKey(schemaId))
            {
                swaggerDoc.Components.Schemas.Add(schemaId, schema);
            }
        }
    }
}

注意事项

  • 上述实现会自动递归处理所有顶层类型依赖的嵌套自定义类型,不需要手动枚举所有嵌套类。
  • 配置完成后重启应用,直接访问/swagger/v1/swagger.json即可在components.schemas节点下看到所有新增的类型定义,NSwag Studio读取该json文件可正常生成对应的前端类型代码。
  • 不需要额外调用RegisterType方法,上述逻辑已经覆盖schema生成、挂载的全流程。

内容的提问来源于stack exchange,提问作者Geoff Olding

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 12:33:13