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

React Native使用ImagePicker向.NET Core API发Post请求遇400错误

解决React Native Axios上传FormData到.NET Core API的400错误问题

我来帮你搞定这个上传的400错误问题,之前我也踩过类似的坑,核心问题出在参数传递方式不对和前后端FormData格式不匹配上,咱们分客户端和服务端一步步修复:

一、React Native客户端代码修正

1. 先把Axios的参数传对

你现在把fotos作为Axios post的第三个参数传了,但Axios的post方法第三个参数是请求配置(比如headers),不是请求数据。得把fotos的字段合并到FormData里,或者作为URL参数带过去。

2. 对齐前后端的字段名

后端接收文件的参数是IFormFileCollection arquivo,所以你在FormData里append文件的时候,key必须是arquivo,而不是file,不然后端识别不到文件集合。

3. 处理跨平台的URI差异

React Native的ImagePicker在iOS和Android返回的URI格式不一样:iOS是file://开头,Android可能是content://,得统一处理成Axios能正确解析的格式,最简单的就是给iOS的URI去掉file://前缀。

修改后的客户端代码:

handledUpload = async () => { // 把async提到外层,避免嵌套async的麻烦
  try {
    const upload = await ImagePicker.launchImageLibrary({}); // 用await更直观,避免回调嵌套
    if (!upload.uri) return; // 用户取消选择的情况直接返回

    const arquivo = new FormData();
    // 处理URI格式:iOS去掉file://前缀,Android保持原样
    const fileUri = Platform.OS === 'ios' ? upload.uri.replace('file://', '') : upload.uri;
    // 注意key是'arquivo',和后端参数名严格一致
    arquivo.append('arquivo', { 
      uri: fileUri, 
      type: upload.type || 'image/jpeg', // 兜底类型,防止返回null导致错误
      name: upload.fileName || `img-${Date.now()}.jpg` // 兜底文件名,避免无文件名的情况
    });

    // 把fotos的字段逐个加到FormData里
    arquivo.append('Id', '1');
    arquivo.append('IdUsuario', '1');
    arquivo.append('NumCode', '4');

    // 发送请求,这里不需要额外传fotos参数
    const response = await api.post(`galeria/UploadArquivos/`, arquivo, {
      headers: {
        // 让Axios自动处理multipart/form-data的boundary,别手动写boundary,会出错
        'Content-Type': 'multipart/form-data'
      }
    });
    console.log('上传成功啦:', response.data);
  } catch (error) {
    // 打印详细错误信息,方便调试
    console.error('上传失败:', error.response?.data || error.message);
  }
};

二、.NET Core服务端代码修正

1. 给参数加上[FromForm]标记

因为是multipart/form-data请求,必须告诉框架从表单里读取参数,所以要给arquivo和fotos都加上[FromForm]标记。另外,你的Consumes属性可以只保留multipart/form-data,因为上传文件只用这个类型。

修改后的服务端代码:

[HttpPost]
[Route("UploadArquivos")]
[Consumes("multipart/form-data")] // 只保留需要的类型即可
public IEnumerable<Galeria> UploadArquivos([FromForm] IFormFileCollection arquivo, [FromForm] Galeria fotos) 
{
    // 现在可以正常拿到文件和fotos数据了,先加个调试输出看看
    if (arquivo != null && arquivo.Count > 0)
    {
        foreach (var file in arquivo)
        {
            Console.WriteLine($"收到文件:{file.FileName},大小:{file.Length}字节");
        }
    }
    Console.WriteLine($"Fotos参数:Id={fotos.Id}, IdUsuario={fotos.IdUsuario}, NumCode={fotos.NumCode}");

    // 接下来写你的文件存储逻辑就行
    return new List<Galeria>(); // 按你的业务需求返回数据
}

可选:如果不想拆fotos字段(进阶方式)

要是你不想把fotos的字段一个个拆到FormData里,也可以在客户端把fotos转成JSON字符串,append到FormData里,后端再反序列化:

客户端追加一行:

arquivo.append('fotos', JSON.stringify({ Id: 1, IdUsuario: 1, NumCode: 4 }));

服务端修改参数:

public IEnumerable<Galeria> UploadArquivos([FromForm] IFormFileCollection arquivo, [FromForm] string fotos) 
{
    var galeria = JsonSerializer.Deserialize<Galeria>(fotos);
    // 后续逻辑和之前一样
}

三、调试小技巧

  1. 客户端看请求详情:给Axios加个拦截器,打印请求的headers和FormData内容,确认参数是不是和你预期的一样;
  2. 用Postman先测后端:先在Postman里构造一个multipart/form-data请求,上传文件+参数,测试后端接口是否正常,排除后端本身的问题;
  3. 检查CORS配置:确保后端的CORS允许你的React Native应用访问,并且允许multipart/form-data请求类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:49:55