Swashbuckle多部分表单序列化:Options类型在Swagger规范的展示问题
让Swagger将FromForm绑定的DTO作为独立类型展示的解决方案
问题场景
控制器方法同时接收IFormFile文件参数和带[FromForm]特性的Options DTO参数,默认Swashbuckle会将Options的属性与file平级展开,无法体现Options作为独立类型的结构;若移除[FromForm],Options会被识别为查询参数,不符合表单提交的需求。
解决方案
1. 实现自定义Swagger Schema过滤器
创建一个ISchemaFilter实现类,识别带[FromForm]特性的复杂类型参数,将其Schema转为对独立类型定义的引用,而非平展属性:
using Microsoft.OpenApi.Models; using Swashbuckle.AspNetCore.SwaggerGen; using System.Reflection; public class FormDtoSchemaFilter : ISchemaFilter { public void Apply(OpenApiSchema schema, SchemaFilterContext context) { if (context.ApiModel?.Kind == Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadataKind.Parameter) { var parameterInfo = context.ApiModel.Container as ParameterInfo; if (parameterInfo != null && parameterInfo.GetCustomAttribute<FromFormAttribute>() != null) { var dtoType = parameterInfo.ParameterType; // 将DTO类型添加到Swagger定义集合 if (!context.SchemaRepository.Schemas.ContainsKey(dtoType.Name)) { var dtoSchema = context.SchemaGenerator.GenerateSchema(dtoType, context.SchemaRepository); context.SchemaRepository.Schemas[dtoType.Name] = dtoSchema; } // 修改当前参数的Schema为引用类型 schema.Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = dtoType.Name }; // 清空原有平展的属性 schema.Properties.Clear(); schema.Type = null; } } } }
2. 注册过滤器到Swagger配置
在项目的Swagger服务配置中(如Program.cs),添加上述过滤器:
builder.Services.AddSwaggerGen(c => { c.SchemaFilter<FormDtoSchemaFilter>(); // 其他Swagger配置项(如文档信息、XML注释等) });
3. 确保ModelBinder正常工作
如果使用了自定义ModelBinder,需保证它能正确从表单数据中绑定Options对象。若无需自定义逻辑,可移除[ModelBinder]特性,使用默认模型绑定即可。
效果验证
配置完成后,Swagger文档会将Options作为独立的Schema类型展示,TestMethod的options参数会显示为对Options类型的引用,同时保持其为表单数据的一部分,不会转为查询参数。
内容的提问来源于stack exchange,提问作者Max
相关产品推荐
相关产品推荐

