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

如何让Swagger.json标识列表/数组内的可空类型?

问题

希望Swagger.json能包含列表或数组内可空类型的信息,现有模型、Swagger配置及生成的JSON如下:

模型代码

public class AccountSettingsDto
{
    public int Id { get; set; }
    public decimal? Value { get; set; }
    public List<decimal?> ListValue { get; set; }
    public decimal?[] ArrayValue { get; set; }
}

当前Swagger配置

services.AddSwaggerGen(config =>
{
    config.MapType<decimal>(() => new OpenApiSchema { Type = "number", Format = "decimal" });
    config.UseAllOfToExtendReferenceSchemas();
});

生成的Swagger JSON片段

"AccountSettingsDto": {
    "type": "object",
    "properties": {
      "id": {
        "type": "integer",
        "format": "int32"
      },
      "value": {
        "type": "number",
        "format": "decimal",
        "nullable": true
      },
      "listValue": {
        "type": "array",
        "items": {
          "type": "number",
          "format": "decimal"
        },
        "nullable": true
      },
      "arrayValue": {
        "type": "array",
        "items": {
          "type": "number",
          "format": "decimal"
        },
        "nullable": true
      }
    },
    "additionalProperties": false
}

可见Value属性的可空标识正确,但列表/数组内的元素未正确标记可空。曾尝试添加config.MapType<decimal?>(() => new OpenApiSchema { Type = "number", Format = "decimal?" });但无效。


解决方案

要让数组/列表的元素显示可空标识,需通过SchemaFilter遍历并修改数组的items schema——MapType仅针对顶层属性类型,无法处理嵌套在数组内的可空类型。

步骤1:实现自定义SchemaFilter

创建NullableArrayItemSchemaFilter类,实现ISchemaFilter接口,检查数组元素是否为可空值类型,为items添加nullable: true标识:

using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
using System.Reflection;

public class NullableArrayItemSchemaFilter : ISchemaFilter
{
    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        if (schema.Type == "array" && schema.Items != null)
        {
            var propertyInfo = context.MemberInfo as PropertyInfo;
            if (propertyInfo == null) return;

            // 提取数组/列表的元素类型
            Type elementType = null;
            if (propertyInfo.PropertyType.IsArray)
            {
                elementType = propertyInfo.PropertyType.GetElementType();
            }
            else if (propertyInfo.PropertyType.IsGenericType && 
                     propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(List<>))
            {
                elementType = propertyInfo.PropertyType.GetGenericArguments()[0];
            }

            // 标记可空值类型的元素为nullable
            if (elementType != null && elementType.IsGenericType && 
                elementType.GetGenericTypeDefinition() == typeof(Nullable<>))
            {
                schema.Items.Nullable = true;
                // 确保decimal类型的格式正确
                if (elementType.GetGenericArguments()[0] == typeof(decimal))
                {
                    schema.Items.Type = "number";
                    schema.Items.Format = "decimal";
                }
            }
        }
    }
}

步骤2:注册SchemaFilter到Swagger配置

修改AddSwaggerGen配置,添加自定义过滤器:

services.AddSwaggerGen(config =>
{
    config.MapType<decimal>(() => new OpenApiSchema { Type = "number", Format = "decimal" });
    config.UseAllOfToExtendReferenceSchemas();
    // 注册自定义过滤器
    config.SchemaFilter<NullableArrayItemSchemaFilter>();
});

最终效果

修改后生成的Swagger JSON中,数组的items会包含nullable: true:

"listValue": {
    "type": "array",
    "items": {
      "type": "number",
      "format": "decimal",
      "nullable": true
    },
    "nullable": true
},
"arrayValue": {
    "type": "array",
    "items": {
      "type": "number",
      "format": "decimal",
      "nullable": true
    },
    "nullable": true
}

补充说明

之前尝试的MapType<decimal?>无效,是因为Swashbuckle处理数组元素时,不会直接复用MapType配置的可空类型映射,而是解析元素原始类型生成schema,因此必须通过SchemaFilter手动处理嵌套的可空元素。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 16:02:53