ASP.NET Core同项目下MVC与Web API文件上传时IFormfile出现Illegal invocation及Null Value问题求助
解决ASP.NET Core中Web API+MVC文件上传的Null/Illegal Invocation问题
你遇到的问题本质是文件上传的前端数据格式错误,以及后端跨服务传递文件时的序列化方式不对——IFormFile无法通过JSON序列化传递,必须用multipart/form-data格式来处理。下面一步步帮你修复:
一、修复前端AJAX代码
你之前注释processData: false是因为没正确使用FormData,直接传普通对象会导致文件无法被正确解析,反而让后端绑定失败。正确的做法是用FormData包装所有数据:
function SaveExit() { var formData = new FormData(); // 添加普通表单字段 formData.append("Total", $("#Total").val()); // 添加文件,注意name要和FormVM的Attachments属性名完全一致 var fileInput = $('[name="file"]')[0]; if (fileInput.files.length > 0) { formData.append("Attachments", fileInput.files[0]); } $.ajax({ url: "/Forms/InsertForm", type: "Post", data: formData, dataType: 'json', // 这两个参数必须设置,否则jQuery会自动编码数据,破坏文件结构 processData: false, contentType: false, success: function (result) { window.location.href = "/Reimbusments/Expense"; }, error: function (error) { console.log(error); } }); return false; }
说明:
FormData是浏览器专门用来处理multipart/form-data格式的对象,能正确兼容文件和普通字段。processData: false禁止jQuery把FormData转成查询字符串,contentType: false让浏览器自动生成带boundary的正确请求头。
二、修正MVC控制器的接收逻辑
确保MVC控制器能正确识别multipart/form-data格式的数据,显式添加[FromForm]注解可以避免绑定歧义:
[HttpPost] public JsonResult InsertForm([FromForm] FormVM formVM) { var sessionExpense = HttpContext.Session.GetString("ExpenseID"); var result = formRepository.InsertForm(formVM, sessionExpense); return Json(result); }
三、修复仓储层调用Web API的代码
你之前用StringContent把FormVM序列化成JSON传给API是错误的——IFormFile无法被JSON序列化,API端会直接绑定失败。必须用MultipartFormDataContent来传递数据和文件:
public async Task<HttpStatusCode> InsertForm(FormVM entity, string expenseid) { entity.ExpenseId = Int32.Parse(expenseid); var multipartContent = new MultipartFormDataContent(); // 添加普通字段 multipartContent.Add(new StringContent(entity.Total.ToString()), "Total"); multipartContent.Add(new StringContent(entity.ExpenseId.ToString()), "ExpenseId"); // 添加文件流 if (entity.Attachments != null && entity.Attachments.Length > 0) { var fileContent = new StreamContent(entity.Attachments.OpenReadStream()); fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse(entity.Attachments.ContentType); multipartContent.Add(fileContent, "Attachments", entity.Attachments.FileName); } // 用异步调用代替.Result,避免线程阻塞死锁 var result = await httpClient.PostAsync(address.link + request + "FormInsert", multipartContent); return result.StatusCode; }
四、确保Web API控制器能正确接收
Web API默认会尝试从JSON请求体绑定数据,所以你的FormInsert接口必须显式标注[FromForm]:
[HttpPost("FormInsert")] public IActionResult FormInsert([FromForm] FormVM formVM) { // 你的业务逻辑处理 return Ok(); }
总结
- 前端必须用
FormData配合正确的AJAX参数传递文件 - 后端MVC和API都要通过
[FromForm]绑定包含IFormFile的模型 - 跨服务传递文件时,绝对不能用JSON序列化,必须用
multipart/form-data格式
内容的提问来源于stack exchange,提问作者Bagoes Heikhal
相关产品推荐
相关产品推荐

