React/TypeScript传图片至C# API报错:JSON无法转为System.Byte[]
图片上传:React+TypeScript前端到C# API的问题解决
问题分析
你遇到的两个错误根源:
- 前端直接以JSON格式传递
File对象,无法被后端正确解析为byte[] - 后端默认期望JSON格式请求体,但文件上传需用multipart/form-data表单格式,导致
postRecipeDto无法正确绑定
解决方案
前端修改(React+TypeScript)
改用FormData包装数据,这是文件上传的标准方式:
const handleRecipeUpload = () => { const formData = new FormData(); // 追加普通字段 formData.append('Name', recipeData.Name || ''); formData.append('Description', recipeData.Description || ''); formData.append('Country', recipeData.Country || ''); formData.append('IngridientList', recipeData.IngridientList || ''); formData.append('CookingTimeInMins', recipeData.CookingTimeInMins.toString()); // 追加文件 if (recipeData.RecipePhoto) { formData.append('RecipePhoto', recipeData.RecipePhoto); } axios.post('https://localhost:7104/api/Recipe/Post', formData, { headers: { 'Content-Type': 'multipart/form-data' } }) .then((response) => { console.log(response); }) .catch((error) => { console.log(error); console.log(JSON.stringify(error.response?.data?.errors)); }); };
后端修改(C# API)
- 修改DTO模型:将
byte[]替换为IFormFile(ASP.NET Core专门处理上传文件的类型)
public class PostRecipeDto { public string? Name { get; set; } public string? Description { get; set; } public string? Country { get; set; } public string? IngridientList { get; set; } public int CookingTimeInMins { get; set; } public IFormFile? RecipePhoto { get; set; } // 替换原byte[]类型 }
- 修改控制器方法:添加
[FromForm]特性,指定从表单数据绑定参数
[HttpPost] [Route("Post")] public async Task<IActionResult> PostRecipeAsync([FromForm] PostRecipeDto postRecipeDto) { return Ok(await _postRecipeServices.PostRecipeService(postRecipeDto)); }
- 服务层转byte[](可选):如果业务需要字节数组,在服务中转换
IFormFile
public async Task<YourReturnType> PostRecipeService(PostRecipeDto dto) { byte[]? photoBytes = null; if (dto.RecipePhoto != null && dto.RecipePhoto.Length > 0) { using var memoryStream = new MemoryStream(); await dto.RecipePhoto.CopyToAsync(memoryStream); photoBytes = memoryStream.ToArray(); } // 后续业务逻辑处理 }
关键说明
FormData能正确处理文件与普通字段的混合上传,是浏览器原生支持的标准方案IFormFile不仅能接收文件内容,还能获取文件名、大小等元数据,比直接用byte[]更灵活- 必须添加
[FromForm],否则框架会尝试从JSON请求体绑定参数,导致参数为空
内容的提问来源于stack exchange,提问作者Kond Videos
相关产品推荐
相关产品推荐

