如何让Swagger UI显示BaseRequestDto的请求示例及继承文档示例?
让Swagger包含基类继承的文档和示例数据的解决方法
下面是几种实用的解决思路,帮你让Swagger正确展示基类的<summary>和<example>标签内容:
方案一:自定义Schema过滤器合并基类元数据
通过实现Swashbuckle的ISchemaFilter,手动将基类的文档和示例数据合并到派生类的Schema中:
- 创建过滤器类
using Microsoft.OpenApi.Models; using Swashbuckle.AspNetCore.SwaggerGen; using System.Reflection; public class InheritedDocsSchemaFilter : ISchemaFilter { public void Apply(OpenApiSchema schema, SchemaFilterContext context) { var currentType = context.Type; // 遍历所有基类(直到object) while (currentType.BaseType != null && currentType.BaseType != typeof(object)) { foreach (var baseProperty in currentType.BaseType.GetProperties(BindingFlags.Public | BindingFlags.Instance)) { // 跳过当前Schema未包含的属性 if (!schema.Properties.ContainsKey(baseProperty.Name)) continue; // 同步基类属性的Summary描述 var summaryAttr = baseProperty.GetCustomAttribute<System.ComponentModel.DataAnnotations.Schema.DisplayAttribute>(); if (summaryAttr != null && !string.IsNullOrWhiteSpace(summaryAttr.Description)) { schema.Properties[baseProperty.Name].Description = summaryAttr.Description; } // 同步基类属性的Example示例 var exampleAttr = baseProperty.GetCustomAttribute<Swashbuckle.AspNetCore.Annotations.SwaggerExampleAttribute>(); if (exampleAttr != null) { var exampleInstance = Activator.CreateInstance(exampleAttr.ExampleType); schema.Properties[baseProperty.Name].Example = exampleInstance; } } currentType = currentType.BaseType; } } }
- 在Swagger配置中注册过滤器
在Program.cs或Startup.cs的Swagger服务配置里添加:
builder.Services.AddSwaggerGen(c => { c.SchemaFilter<InheritedDocsSchemaFilter>(); // 其他Swagger配置(比如文档标题、版本等) });
方案二:确保XML文档被正确扫描
如果你依赖XML文档文件来读取<summary>标签,需要确保基类所在项目的XML文档被Swagger加载:
开启基类项目的XML文档生成
在基类项目的属性设置中,勾选"输出"->"XML文档文件",并记录生成路径。在WebAPI项目中加载该XML文件
builder.Services.AddSwaggerGen(c => { // 加载基类项目的XML文档 var baseClassXmlPath = Path.Combine(AppContext.BaseDirectory, "YourBaseClassProjectName.xml"); c.IncludeXmlComments(baseClassXmlPath); // 同时加载WebAPI自身的XML文档(如果有的话) var apiXmlPath = Path.Combine(AppContext.BaseDirectory, "YourWebApiProjectName.xml"); c.IncludeXmlComments(apiXmlPath); });
方案三:备选:改用组合模式(按需选择)
如果继承结构带来的文档问题难以解决,可以考虑将BaseRequestDto作为派生类的一个公共属性,而非直接继承。这种方式能避免继承带来的元数据丢失问题,但需要调整现有DTO的结构。
内容的提问来源于stack exchange,提问作者Navid_pdp11
相关产品推荐
相关产品推荐

