ASP.NET Core MVC表单上传图片至Web API时参数传递失败问题
问题原因
你的API接口用[FromForm]接收表单数据(包含文件),但MVC端调用时用了PostAsJsonAsync发送JSON格式请求,两者完全不兼容:
[FromForm]期望请求是multipart/form-data或application/x-www-form-urlencoded格式,JSON请求无法被解析为表单对象。IFormFile类型不能通过JSON序列化传递,必须通过multipart/form-data格式上传。
解决方案
1. 修正MVC的AddStudent方法
移除不必要的ModelState.Remove("Pic"),确保文件能正确绑定到student.Pic,同时补全RedirectToAction的return语句:
[HttpPost] public async Task<IActionResult> AddStudent(Student student) { ModelState.Remove("PicUrl"); // 保留这个,因为API会生成PicUrl if (ModelState.IsValid) { var response = await webApiExecuter.InvokePostWithFormData<Student>("student", student, student.Pic); if (response != null) { return RedirectToAction(nameof(Index)); // 补上return,否则不会跳转 } return View(student); } return View(student); }
2. 新增支持表单+文件的API调用方法
替换原来的InvokePost,改用MultipartFormDataContent构建符合API要求的请求:
public async Task<T?> InvokePostWithFormData<T>(string relativeUrl, Student student, IFormFile? pic) { var httpClient = httpClientFactory.CreateClient(name); using var content = new MultipartFormDataContent(); // 逐个添加Student的属性到表单数据 content.Add(new StringContent(student.Id.ToString()), "Id"); content.Add(new StringContent(student.Name ?? string.Empty), "Name"); if (student.Age.HasValue) content.Add(new StringContent(student.Age.Value.ToString()), "Age"); content.Add(new StringContent(student.Gender ?? string.Empty), "Gender"); if (student.RollNumber.HasValue) content.Add(new StringContent(student.RollNumber.Value.ToString()), "RollNumber"); content.Add(new StringContent(student.Standard ?? string.Empty), "Standard"); if (student.Section.HasValue) content.Add(new StringContent(student.Section.Value.ToString()), "Section"); if (student.Birthday.HasValue) content.Add(new StringContent(student.Birthday.Value.ToString("o")), "Birthday"); content.Add(new StringContent(student.BloodGroup ?? string.Empty), "BloodGroup"); // 添加文件到表单 if (pic != null && pic.Length > 0) { var fileStreamContent = new StreamContent(pic.OpenReadStream()); fileStreamContent.Headers.ContentType = new MediaTypeHeaderValue(pic.ContentType); content.Add(fileStreamContent, "Pic", pic.FileName); } var res = await httpClient.PostAsync(relativeUrl, content); res.EnsureSuccessStatusCode(); return await res.Content.ReadFromJsonAsync<T>(); }
3. 验证视图绑定
确保视图中的文件上传控件正确绑定到Pic属性:
<input type="file" asp-for="Pic" accept=".jpg" />
关键说明
- 必须用
MultipartFormDataContent构建包含文件的表单请求,才能匹配API的[FromForm]接收规则。 - 日期类型按ISO格式(
ToString("o"))传递,避免跨系统解析错误。 - 提前确认HttpClient的BaseAddress已正确配置为你的Web API地址。
内容的提问来源于stack exchange,提问作者Sayeed Ahmed
相关产品推荐
相关产品推荐

