Swashbuckle如何显示字典示例替代additionalProp默认占位
Swashbuckle字典属性XML示例不生效解决方案
问题原因
Swashbuckle 默认对 Dictionary<string, TValue> 类型的Schema生成逻辑走附加属性规则,不会自动读取XML注释中<example>标签配置的字典示例值,默认只会生成additionalProp1、additionalProp2这类固定占位符,需要通过自定义Schema过滤器实现自定义字典示例的读取加载。
操作步骤
- 首先确认项目已开启XML注释文件生成,且Swagger配置中已添加XML注释加载逻辑(你的string类型示例能正常生效,说明这一步已经配置完成)
- 修正XML注释的示例写法:你原有代码中字典属性的example标签内容外层多余包裹了一层转义双引号,会导致读取失败,修正后的类定义如下:
public class SimpleClass { /// <example>{"age":31,"height":234}</example> public Dictionary<string, int> DictionaryProperty { get; set; } /// <example>The cow jumped over the moon</example> public string someProperty { get; set; } }
- 新增自定义Schema过滤器,实现字典类型的XML示例读取逻辑:
using Microsoft.OpenApi.Models; using Swashbuckle.AspNetCore.SwaggerGen; using System.Reflection; using System.Text.Json; using System.Xml.Linq; using System.Xml.XPath; public class DictionaryExampleSchemaFilter : ISchemaFilter { private readonly XDocument _xmlCommentsDoc; public DictionaryExampleSchemaFilter(string xmlCommentFilePath) { if (File.Exists(xmlCommentFilePath)) { _xmlCommentsDoc = XDocument.Load(xmlCommentFilePath); } } public void Apply(OpenApiSchema schema, SchemaFilterContext context) { // 仅处理泛型字典类型 if (!context.Type.IsGenericType || context.Type.GetGenericTypeDefinition() != typeof(Dictionary<,>) || _xmlCommentsDoc == null || context.MemberInfo == null) { return; } // 定位当前属性对应的XML注释节点 var memberXPath = $"//member[@name='{XmlCommentsNodeNameHelper.GetMemberNameForFieldOrProperty(context.MemberInfo)}']"; var exampleNode = _xmlCommentsDoc.XPathSelectElement(memberXPath)?.Element("example"); if (exampleNode == null || string.IsNullOrWhiteSpace(exampleNode.Value)) { return; } // 解析示例值写入Schema try { var exampleDict = JsonSerializer.Deserialize<Dictionary<string, object>>(exampleNode.Value.Trim()); schema.Example = OpenApiAnyFactory.CreateFor(schema, exampleDict); // 清除附加属性的默认占位示例,避免冲突 schema.AdditionalProperties.Example = null; } catch { // 示例格式不合法时忽略,走默认生成逻辑 } } }
- 在Swagger服务配置中注册自定义过滤器,传入和现有XML注释加载逻辑一致的文件路径:
var builder = WebApplication.CreateBuilder(args); // 其他服务配置... builder.Services.AddSwaggerGen(options => { var xmlFileName = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlFilePath = Path.Combine(AppContext.BaseDirectory, xmlFileName); // 原有XML注释加载配置 options.IncludeXmlComments(xmlFilePath); // 注册字典示例过滤器 options.SchemaFilter<DictionaryExampleSchemaFilter>(xmlFilePath); });
效果
重新编译启动项目后,Swagger页面的响应示例中,DictionaryProperty字段会直接展示你配置的{"age":31,"height":234},不再显示默认的additionalProp占位内容。
注:如果你的字典值是固定强类型,可将过滤器中反序列化的目标类型替换为对应的
Dictionary<string, 你的值类型>,示例解析精度会更高。
内容的提问来源于stack exchange,提问作者AS3
相关产品推荐
相关产品推荐

