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

React调用.NET API向SQL Server传数据报400错误求助

400 Bad Request 问题排查与解决方案

核心原因分析

Swagger能正常调用接口但前端请求返回400,本质是前端请求格式/参数与后端接收规则不匹配,常见触发点包括:

  • 请求Content-Type与后端接收注解([FromForm]/[FromBody])不匹配
  • 前端提交的字段名与后端模型属性名不一致(大小写、拼写错误)
  • 后端模型标记[Required]的必填字段前端未传值
  • JSON序列化/反序列化时格式错误

针对两种前端提交方式的修正方案

1. 无JSON转换的FormData提交(适用于带文件上传的场景)

如果后端接口用[FromForm]接收表单数据,前端需直接传递FormData,并正确设置请求头:

前端修正代码

import axios from 'axios';

const submitData = async (formValues) => {
  const formData = new FormData();
  // 注意:字段名需与后端模型属性名完全一致(区分大小写)
  formData.append('Name', formValues.name);
  formData.append('Age', formValues.age);
  // 若有文件,直接追加文件对象
  // formData.append('Attachment', formValues.file);

  try {
    const response = await axios.post('/api/your-endpoint', formData, {
      headers: {
        'Content-Type': 'multipart/form-data'
      }
    });
    console.log('提交成功:', response.data);
  } catch (err) {
    console.error('提交失败:', err.response);
  }
};

对应后端代码(需确保用[FromForm])

[HttpPost]
public IActionResult SubmitData([FromForm] YourDataModel model)
{
  if (!ModelState.IsValid)
  {
    // 打印校验错误,方便排查
    var errors = ModelState.SelectMany(x => x.Value.Errors).Select(e => e.ErrorMessage);
    return BadRequest(errors);
  }
  // 数据库写入逻辑
  return Ok();
}

2. 带JSON转换的FormData提交(不推荐,除非特殊场景)

如果后端需要从FormData中读取JSON字符串,需确保键名与后端接收的参数名一致,同时后端要手动反序列化:

前端修正代码

const submitData = async (formValues) => {
  const formData = new FormData();
  // 键名需与后端参数名一致,比如后端用model接收
  formData.append('model', JSON.stringify({
    Name: formValues.name,
    Age: formValues.age
  }));

  try {
    const response = await axios.post('/api/your-endpoint', formData);
    console.log('提交成功:', response.data);
  } catch (err) {
    console.error('提交失败:', err.response);
  }
};

对应后端代码

[HttpPost]
public IActionResult SubmitData([FromForm] string model)
{
  if (string.IsNullOrEmpty(model))
  {
    return BadRequest("模型数据不能为空");
  }
  var dataModel = JsonSerializer.Deserialize<YourDataModel>(model);
  if (!ModelState.IsValid)
  {
    var errors = ModelState.SelectMany(x => x.Value.Errors).Select(e => e.ErrorMessage);
    return BadRequest(errors);
  }
  // 数据库写入逻辑
  return Ok();
}

更简洁的替代方案:直接提交JSON(无文件上传场景优先用)

如果没有文件上传需求,无需使用FormData,直接发送JSON格式数据,匹配后端[FromBody]注解:

前端代码

const submitData = async (formValues) => {
  const data = {
    Name: formValues.name,
    Age: formValues.age
  };

  try {
    const response = await axios.post('/api/your-endpoint', data, {
      headers: {
        'Content-Type': 'application/json'
      }
    });
    console.log('提交成功:', response.data);
  } catch (err) {
    console.error('提交失败:', err.response);
  }
};

对应后端代码

[HttpPost]
public IActionResult SubmitData([FromBody] YourDataModel model)
{
  if (!ModelState.IsValid)
  {
    var errors = ModelState.SelectMany(x => x.Value.Errors).Select(e => e.ErrorMessage);
    return BadRequest(errors);
  }
  // 数据库写入逻辑
  return Ok();
}

快速排查步骤

  1. 打开浏览器开发者工具→Network面板,查看请求的Content-Type和Payload是否与Swagger一致
  2. 检查后端模型的[Required]字段,确认前端都传了有效值
  3. 统一字段名大小写:若后端用PascalCase(如Name),前端需对应;若要支持前端camelCase,可在后端配置JSON序列化:
// Program.cs
builder.Services.AddControllers()
  .AddJsonOptions(options =>
  {
    options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
  });

后续下载功能对接手机文件存储

后端下载接口实现

[HttpGet("download/{id}")]
public IActionResult DownloadFile(int id)
{
  // 从数据库获取文件数据(示例)
  var fileRecord = _dbContext.FileRecords.Find(id);
  if (fileRecord == null)
  {
    return NotFound();
  }
  // 返回文件流,指定Content-Type和下载文件名
  return File(fileRecord.FileContent, fileRecord.ContentType, fileRecord.FileName);
}

前端(React Native)对接手机存储

使用react-native-fs库实现文件保存:

import RNFS from 'react-native-fs';

const downloadToPhone = async (fileId) => {
  const apiUrl = `https://your-api-domain/api/files/download/${fileId}`;
  // 保存到手机文档目录
  const savePath = `${RNFS.DocumentDirectoryPath}/${fileId}.pdf`;

  try {
    const result = await RNFS.downloadFile({
      fromUrl: apiUrl,
      toFile: savePath
    }).promise;
    
    if (result.statusCode === 200) {
      console.log('文件已保存到:', savePath);
      // 可调用原生API打开文件或通知用户
    }
  } catch (err) {
    console.error('下载失败:', err);
  }
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 01:24:57