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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 05:09:18