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

Swashbuckle.AspNetCore使用[FromForm]时未生成nullable:true问题

问题描述

使用Swashbuckle.AspNetCore 6.4.0时,通过[FromForm]指定multipart/form-data请求类型后,DTO中标记为可选的属性(如string?、可选IFormFile)在生成的Swagger规范里不会带上"nullable": true标记,导致客户端代码生成器传入null时抛出异常。而改用[FromBody](application/json)时,可选属性会正确生成该标记。选择multipart/form-data是因为需要在DTO中上传文件,相比base64编码字节数组更合适。

示例代码

DTO定义

public class TestDTO
{
  public string? SomeProp { get; set; }
}

控制器代码

[ApiController]
[Route("api/[controller]/[action]")]
public class TestController : Controller
{
  [HttpPost]
  public IActionResult Test([FromForm] TestDTO dto)
  {
    return this.Ok(dto);
  }
}

生成的Swagger差异

使用[FromForm]时的Swagger片段

"/api/Test/Test": {
   "post": {
     "tags": [
       "Test"
     ],
     "requestBody": {
       "content": {
         "multipart/form-data": {
           "schema": {
             "type": "object",
             "properties": {
               "SomeProp": {
                 "type": "string"
               }
             }
           },
           "encoding": {
             "SomeProp": {
               "style": "form"
             }
           }
         }
       }
     },
     "responses": {
       "200": {
         "description": "Success"
       }
     }
   }
}

SomeProp未包含"nullable": true标记。

使用[FromBody]时的Swagger片段

接口定义:

"/api/Test/Test": {
      "post": {
        "tags": [
          "Test"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TourificService.Endpoints.Admin.Controllers.TestDTO"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success"
          }
        }
      }
}

对应的组件定义:

"TourificService.Endpoints.Admin.Controllers.TestDTO": {
        "type": "object",
        "properties": {
          "someProp": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
}

someProp正确带有"nullable": true标记。

临时解决方案(不推荐)

手动在Swagger JSON中为可选属性添加"nullable": true后再传给客户端代码生成器,但该方式需要手动干预,违背自动代码生成的初衷。

可行解决方案

方案1:自定义Schema过滤器

创建一个Schema过滤器,识别[FromForm]绑定的DTO属性,为可空类型自动添加nullable: true标记:

public class FormDataNullableSchemaFilter : ISchemaFilter
{
    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        // 判断当前类型是否为FromForm绑定的DTO
        var isFromFormDto = context.ApiModel.ParameterDescriptions.Any(p => 
            p.BindingInfo?.BinderType == typeof(FormFileModelBinder) ||
            p.BindingInfo?.BindingSource == BindingSource.Form);
        
        if (!isFromFormDto) return;

        foreach (var property in schema.Properties)
        {
            var propertyInfo = context.Type.GetProperty(property.Key, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
            if (propertyInfo == null) continue;

            // 检查属性是否为可空值类型或可空引用类型
            var isNullable = Nullable.GetUnderlyingType(propertyInfo.PropertyType) != null ||
                            (propertyInfo.PropertyType.IsReferenceType && 
                             Attribute.IsDefined(propertyInfo, typeof(NullableAttribute)));

            if (isNullable)
            {
                property.Value.Nullable = true;
            }
        }
    }
}

在Swagger配置中注册该过滤器:

services.AddSwaggerGen(c =>
{
    c.SchemaFilter<FormDataNullableSchemaFilter>();
    // 其他Swagger配置
});

方案2:升级Swashbuckle.AspNetCore版本

该问题在Swashbuckle.AspNetCore 6.5.0及以上版本中已被修复,升级到最新稳定版本后,[FromForm]绑定的DTO可空属性会自动生成"nullable": true标记。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 09:05:22