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

ASP.NET Core的SwaggerGen能否将[FromForm]嵌套对象保留为JSON输入结构?

可以实现,无需手动编写完整的OpenApi规则,通过SwaggerGen内置配置配合轻量的自定义扩展即可达到预期效果,完整方案如下:

步骤1:配置Swagger复杂类型映射

首先让Swagger识别到嵌套的Dto类型不需要拆分为独立表单字段,而是作为JSON字符串输入:

  • 方案A:仅针对单个Dto适配,直接在SwaggerGen注册时添加类型映射
builder.Services.AddSwaggerGen(c =>
{
    c.MapType<SomeDto>(() => new OpenApiSchema
    {
        Type = "string",
        Format = "json",
        Description = "JSON格式的Dto参数,结构与原有FromBody模式下的dto字段完全一致"
    });
});
  • 方案B:批量适配所有嵌套复杂类型,自定义SchemaFilter全局处理
// 自定义Schema过滤器
public class FormComplexTypeAsJsonFilter : ISchemaFilter
{
    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        // 仅处理FromForm绑定的请求参数
        if (context.ParameterInfo?.CustomAttributes.Any(a => a.AttributeType == typeof(FromFormAttribute)) != true)
            return;

        foreach (var prop in schema.Properties)
        {
            var propType = context.Type.GetProperty(prop.Key)?.PropertyType;
            // 跳过基础类型、字符串、IFormFile相关类型
            if (propType == null 
                || propType.IsPrimitive 
                || propType.IsValueType 
                || propType == typeof(string) 
                || typeof(IFormFile).IsAssignableFrom(propType) 
                || typeof(IEnumerable<IFormFile>).IsAssignableFrom(propType))
                continue;

            // 复杂类型映射为JSON字符串
            prop.Value.Type = "string";
            prop.Value.Format = "json";
            prop.Value.Description += "(JSON格式)";
        }
    }
}

// 注册过滤器
builder.Services.AddSwaggerGen(c =>
{
    c.SchemaFilter<FormComplexTypeAsJsonFilter>();
});

步骤2:添加自定义模型绑定器(可选,推荐)

ASP.NET Core默认不会自动反序列化表单中的JSON字符串为对象,添加自定义模型绑定器实现自动转换,无需修改业务代码:

public class FormJsonModelBinder : IModelBinder
{
    public async Task BindModelAsync(ModelBindingContext bindingContext)
    {
        var valueResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        if (valueResult == ValueProviderResult.None || string.IsNullOrEmpty(valueResult.FirstValue))
            return;

        try
        {
            var model = JsonSerializer.Deserialize(valueResult.FirstValue, 
                bindingContext.ModelType, 
                new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
            bindingContext.Result = ModelBindingResult.Success(model);
        }
        catch
        {
            bindingContext.ModelState.TryAddModelError(bindingContext.ModelName, "JSON格式不符合要求");
        }
        await Task.CompletedTask;
    }
}

在对应的Dto类上添加绑定器特性即可:

[ModelBinder(BinderType = typeof(FormJsonModelBinder))]
public class SomeDto
{
    public string someString {get; set;}
    public int someInt {get; set;}
}

最终效果

配置完成后Swagger UI的表单区域会保留dto作为独立输入框,支持直接输入原有格式的JSON内容,同时IFormFile字段会渲染为正常的文件选择控件,前端仅需将原有Body JSON放入dto字段、新增文件字段即可,无需调整原有JSON结构。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 16:36:09