ASP.NET Core MVC 3.1中jQuery AJAX文件上传失败求助
文件上传问题排查与解决方案
问题背景
尝试通过jQuery AJAX上传图片到ASP.NET Core服务器,期望在HomeController的UploadFileUsingJQueryAJAX方法中通过Employee参数获取所有数据。已参考相关解决方案但未解决,控制台报Illegal Invocation错误,参数无法传递到控制器,修改后甚至无法触发控制器方法。实际需求为上传并读取Excel文件,当前以图片上传做测试验证。
相关代码
HomeController 代码
public IActionResult UploadFileUsingJQueryAJAX() { return View(); } [HttpPost] public IActionResult UploadFileUsingJQueryAJAX(Employee emp) { return View(); }
UploadFileUsingJQueryAJAX 视图代码
@{ ViewData["Title"] = "Upload File Using jQuery AJAX"; } <h1>@ViewData["Title"]</h1> <form id="myForm" method="post" enctype="multipart/form-data" asp-action="UploadFileUsingJQueryAJAX" asp-controller="Home"> <table> <tr> <td>First name:</td> <td><input type="text" id="txtFirstName" name="txtFirstName" /></td> </tr> <tr> <td>Last name:</td> <td><input type="text" id="txtLastName" name="txtLastName" /></td> </tr> <tr> <td>Photo:</td> <td><input type="file" id="photo" name="postedFile" /></td> </tr> <tr> <td>Photo:</td> <td><input type="button" value="Submit" onclick="AjaxFormSubmit();" /></td> </tr> </table> </form> @section Scripts { <script src="~/js/upload_file_using_jquery_ajax_script.js"></script> }
Employee 类代码(Models文件夹下)
public class Employee { public int EmpId { get; set; } public string FistName { get; set; } public string LastName { get; set; } public IFormFile Photo { get; set; } }
JavaScript 代码(upload_file_using_jquery_ajax_script.js)
function AjaxFormSubmit() { var url = $('#myForm').attr('action'); var firstName = $('#txtFirstName').val(); var lastName = $('#txtLastName').val(); var photo = $('#photo')[0].files[0]; var model = { url: url, FirstName: firstName, LastName: lastName, Photo: photo }; SubmitForm(firstName, lastName, photo); } function SubmitForm(firstName, lastName, photo) { $.ajax({ type: 'POST', url: '/Home/UploadFileUsingJQueryAJAX', data: { FirstName: firstName, LastName: lastName, Photo: photo }, dataType: 'json', cache: false, beforeSend: function (xhr) { xhr.setRequestHeader("XSRF-TOKEN", $('input:hidden[name="__RequestVerificationToken"]').val()); }, success: function (response) { console.log(response.responseText); if (response.status == "success") { console.log(response.responseText); } }, error: function (err) { alert("Error occurs" + err.responseText); } }); }
问题原因分析
- Illegal Invocation 错误:直接在AJAX的
data中传递File对象会触发该错误,因为jQuery默认会尝试序列化对象,而File对象无法被常规序列化。 - 参数绑定失败:
Employee类中FistName拼写错误,应为FirstName,导致表单字段无法正确绑定。- 视图中文件输入框的
name属性为postedFile,与Employee类的Photo属性名称不匹配,无法完成参数绑定。
- AJAX配置缺失:上传文件必须设置
processData: false和contentType: false,且需使用FormData封装表单数据,而非直接传递对象。
修复步骤
1. 修正Employee类的拼写错误
public class Employee { public int EmpId { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public IFormFile Photo { get; set; } }
2. 修正视图中文件输入框的name属性
将文件输入框的name改为Photo,与Employee类属性一致:
<input type="file" id="photo" name="Photo" />
3. 修改JavaScript代码,使用FormData并配置正确的AJAX参数
function AjaxFormSubmit() { var form = $('#myForm')[0]; var formData = new FormData(form); SubmitForm(formData); } function SubmitForm(formData) { $.ajax({ type: 'POST', url: '/Home/UploadFileUsingJQueryAJAX', data: formData, dataType: 'json', cache: false, processData: false, contentType: false, beforeSend: function (xhr) { xhr.setRequestHeader("XSRF-TOKEN", $('input:hidden[name="__RequestVerificationToken"]').val()); }, success: function (response) { console.log("上传成功"); }, error: function (err) { console.error("上传失败:", err); } }); }
4. 控制器添加文件处理逻辑(可选)
[HttpPost] public IActionResult UploadFileUsingJQueryAJAX(Employee emp) { if (emp.Photo != null && emp.Photo.Length > 0) { var filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/uploads", emp.Photo.FileName); using (var stream = new FileStream(filePath, FileMode.Create)) { emp.Photo.CopyTo(stream); } } return Json(new { status = "success", filename = emp.Photo?.FileName }); }
上传并读取Excel文件的额外步骤
安装Excel处理库:推荐使用
EPPlus,通过NuGet安装:Install-Package EPPlus或.NET CLI命令:
dotnet add package EPPlus控制器中添加Excel读取逻辑:
[HttpPost] public IActionResult UploadExcel(Employee emp) { if (emp.Photo != null && emp.Photo.Length > 0) { using (var package = new ExcelPackage(emp.Photo.OpenReadStream())) { ExcelWorksheet worksheet = package.Workbook.Worksheets.First(); int rowCount = worksheet.Dimension.Rows; int colCount = worksheet.Dimension.Columns; // 遍历读取数据,示例:从第二行开始读取内容 for (int row = 2; row <= rowCount; row++) { string cellValue = worksheet.Cells[row, 1].Text; // 此处可添加数据处理逻辑,如存入数据库 } } } return Json(new { status = "success", message = "Excel读取完成" }); }前端限制文件类型:修改文件输入框,仅允许选择Excel文件:
<input type="file" id="photo" name="Photo" accept=".xlsx,.xls" />
内容的提问来源于stack exchange,提问作者Ashok kumar
相关产品推荐
相关产品推荐

