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

使用Axios上传含JSON与图片的FormData时后端无法接收JSON字段问题

问题解决:Axios上传FormData时JSON对象无法被ASP.NET Core后端解析

问题场景

用Axios上传包含图片和JSON对象的FormData时,遇到两种情况:

  • 将JSON对象转为字符串后以createStoryModel字段加入FormData,后端能接收图片,但无法获取JSON中的字段值
  • 逐个将JSON对象的字段加入FormData,后端能正常接收所有值,但字段过多时操作繁琐

前端代码对比

无效实现(无法解析JSON字段)

export async function createStoryAsync(Title, Category, formFile) {
    let formData = new FormData();
    // 将对象转为JSON字符串后加入FormData
    const json = JSON.stringify({ Title, Category });
    formData.append("createStoryModel", json);
    formData.append("formFile", formFile[0]);

    await axios.post(`${baseURL}/create`, formData);
}

请求Payload:

FORMDATA:
createStoryModel: {"Title":"FADFASD","Category":"fdasfds"}
formFile: (binary)

有效但繁琐的实现

export async function createStoryAsync(Title, Category, formFile) {
    let formData = new FormData();
    // 逐个添加对象字段
    formData.append("Title", Title);
    formData.append("Category", Category);    
    formData.append("formFile", formFile[0]);

    await axios.post(`${baseURL}/create`, formData);
}

请求Payload:

FORMDATA:
Title: 123
Category: 12
formFile: (binary)

后端代码

实体类

public class CreateStoryModel
{
    public string? Title { get; set; }
    public string? Category  { get; set; }
}

控制器接口

[HttpPost("create")]
public async Task<ActionResult> CreateAsync([FromForm]CreateStoryModel createStoryModel, IFormFile? FormFile)
{
    // 业务逻辑
}

原因分析

ASP.NET Core的[FromForm]特性默认是解析FormData中的扁平键值对,它会把FormData里的每个字段直接映射到实体类的对应属性上。而如果把JSON字符串作为单个字段传递,后端无法自动将这个字符串反序列化为CreateStoryModel实体,导致属性值为空。


解决方案

方案1:自动遍历对象字段批量添加到FormData(推荐)

写一个工具函数,自动遍历JSON对象的所有属性并添加到FormData,避免手动逐个操作:

// 工具函数:将对象的所有属性批量添加到FormData
function appendModelToFormData(formData, model) {
    for (const [key, value] of Object.entries(model)) {
        formData.append(key, value);
    }
}

// 使用示例
export async function createStoryAsync(Title, Category, formFile) {
    let formData = new FormData();
    const createStoryModel = { Title, Category };
    // 自动添加所有字段
    appendModelToFormData(formData, createStoryModel);
    formData.append("formFile", formFile[0]);

    await axios.post(`${baseURL}/create`, formData);
}

如果是嵌套对象,可以修改工具函数支持递归:

function appendModelToFormData(formData, model, parentKey = '') {
    for (const [key, value] of Object.entries(model)) {
        const currentKey = parentKey ? `${parentKey}.${key}` : key;
        if (typeof value === 'object' && value !== null && !(value instanceof File)) {
            appendModelToFormData(formData, value, currentKey);
        } else {
            formData.append(currentKey, value);
        }
    }
}

方案2:修改后端接收逻辑(不推荐)

如果不想改动前端,可以将后端的参数改为字符串类型,手动反序列化JSON:

[HttpPost("create")]
public async Task<ActionResult> CreateAsync([FromForm]string createStoryModel, IFormFile? FormFile)
{
    // 手动将JSON字符串反序列化为实体类
    var model = System.Text.Json.JsonSerializer.Deserialize<CreateStoryModel>(createStoryModel);
    // 后续业务逻辑
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 07:35:21