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

如何让Swashbuckle为Guid键字典生成合理的Schema和示例?

解决Swashbuckle对Dictionary<Guid, T>的Schema和示例生成问题

我在开发REST接口时,Swashbuckle能为其他GET请求中的FancyEntity生成正常的JSON示例和Schema,但当GET请求返回Dictionary<Guid, HelloWorldEvent>类型时,生成的示例键是additionalPropN,Schema里键标注为<*>:。我想把示例替换为真实的Guid值,同时让Schema显示为string($uuid)。相关代码如下:

public class HelloWorldController(IUniversalEventService<HelloWorldEvent> service)
    : BaseEventController<HelloWorldEvent>(service)
{
    /* ... */
    [HttpGet(GetAllSchedulesRoute)]
    [ProducesResponseType<Dictionary<Guid, HelloWorldEvent>>((int)HttpStatusCode.OK)]
    public override Task<IActionResult> GetAllSchedules(CancellationToken cancel = default) =>
        base.GetAllSchedules(cancel);
    /* ... */
}

当前生成的示例JSON为:

{
  "additionalProp1": {
    "world": "string",
    "sendAt": "2024-02-06T12:46:06.301Z"
  },
  "additionalProp2": {
    "world": "string",
    "sendAt": "2024-02-06T12:46:06.301Z"
  },
  "additionalProp3": {
    "world": "string",
    "sendAt": "2024-02-06T12:46:06.301Z"
  }
}

解决方案

1. 自定义Schema过滤器修正键类型显示

创建一个ISchemaFilter实现类,修改Dictionary<Guid, T>对应的Schema,将键的类型指定为string($uuid)格式:

public class GuidDictionarySchemaFilter : ISchemaFilter
{
    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        // 仅处理Dictionary<Guid, T>类型
        if (!context.Type.IsGenericType || 
            context.Type.GetGenericTypeDefinition() != typeof(Dictionary<,>) ||
            context.Type.GetGenericArguments()[0] != typeof(Guid))
        {
            return;
        }

        // 配置键为UUID格式的字符串
        schema.PatternProperties = new Dictionary<string, OpenApiSchema>
        {
            ["^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"] = schema.AdditionalProperties
        };
        // 移除默认的additionalProps描述,改用PatternProperties展示UUID规则
        schema.AdditionalPropertiesAllowed = false;
        schema.Properties.Clear();
    }
}

在Swagger注册时添加这个过滤器:

builder.Services.AddSwaggerGen(c =>
{
    c.SchemaFilter<GuidDictionarySchemaFilter>();
    // 其他Swagger配置项
});

2. 自定义示例过滤器生成带Guid键的示例

创建IExampleFilter实现类,生成包含真实Guid值的示例数据:

public class GuidDictionaryExampleFilter : IExampleFilter
{
    public void Apply(OpenApiExample example, ExampleFilterContext context)
    {
        // 仅处理Dictionary<Guid, T>类型
        if (!context.Type.IsGenericType || 
            context.Type.GetGenericTypeDefinition() != typeof(Dictionary<,>) ||
            context.Type.GetGenericArguments()[0] != typeof(Guid))
        {
            return;
        }

        var valueType = context.Type.GetGenericArguments()[1];
        // 利用Swashbuckle内置示例生成器创建实体示例
        var entityExample = context.SchemaGenerator.GenerateExample(valueType);
        
        // 构建带Guid键的字典示例
        var exampleDict = new Dictionary<Guid, object>
        {
            { Guid.Parse("3fa85f64-5717-4562-b3fc-2c963f66afa6"), entityExample },
            { Guid.Parse("7b2d8c0a-1e3f-4a5b-9c7d-8e9f0a1b2c3d"), entityExample }
        };

        example.Value = OpenApiAnyFactory.CreateFromJson(
            System.Text.Json.JsonSerializer.Serialize(exampleDict)
        );
    }
}

注册示例过滤器:

builder.Services.AddSwaggerGen(c =>
{
    c.ExampleFilter<GuidDictionaryExampleFilter>();
    // 其他Swagger配置项
});

3. 组合使用两个过滤器

将上述两个过滤器同时注册,即可同时实现Schema键类型显示为string($uuid),并生成带真实Guid的示例JSON。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 18:12:38