Kendo Upload向ASP.NET Core上传文件失败的解决问询
问题:Kendo Upload结合AJAX上传文件并传递额外参数到ASP.NET Core失败
客户端初始代码
Kendo Upload控件(CSHTML)
@(Html.Kendo().Upload() .Name("employeeDocument") .Messages(m => m.Select("Select")) .Multiple(false) .Events(e => e.Select("onSelect")) .Validation(validatoin => validatoin.AllowedExtensions(new string[] { ".jpeg", ".jpg", ".png", ".doc", ".docx", ".xls", ".xlsx", ".pdf", ".htm", ".html", ".eml", ".msg" })))
初始JavaScript代码
var fileData = null; function onSelect(e) { fileData = e.files[0]; } function onClickUploadEmployeeDocument(e) { var formData = { employeeDocumentFile: fileData, employeeId: $("#EmployeeId").val(), fiscalPeriodId: $("#FiscalPeriodId").val() }; console.log(formData); var _url = "/Statement/EmployeeDocumentUpload?handler=FileUpload"; $.ajax({ type: "POST", url: _url, data: formData, content: "application/json; charset=utf-8", headers: { "RequestVerificationToken": $('input[name="__RequestVerificationToken"]').val() }, success: function (response) { if (response.success) { window.parent.$("#employeeFileUploadWnd").data("kendoWindow").close(); window.parent.rebindEmployeeDocumentsGrid(); } }, error: function (xhr, textStatus, errorThrown) { } }); }
触发上传时的错误信息
jquery.min.js:2 Uncaught TypeError: Illegal invocation at i (jquery.min.js:2:72390) at qt (jquery.min.js:2:72282) at qt (jquery.min.js:2:72305) at qt (jquery.min.js:2:72305) at k.param (jquery.min.js:2:72601) at Function.ajax (jquery.min.js:2:75981) at init.onClickUploadEmployeeDocument (EmployeeDocumentUpload?employeeId=4430&fiscalPeriodId=3:90:11) at init.trigger (kendo.all.js:164:37) at init._click (kendo.all.js:30687:54) at HTMLSpanElement.i (jquery.min.js:2:87485)
以及:
jquery.min.js:2 Uncaught (in promise) TypeError: Failed to execute 'arrayBuffer' on 'Blob': Illegal invocation at i (jquery.min.js:2:72390) at qt (jquery.min.js:2:72282) at qt (jquery.min.js:2:72305) at qt (jquery.min.js:2:72305) at k.param (jquery.min.js:2:72601) at Function.ajax (jquery.min.js:2:75981) at init.onClickUploadEmployeeDocument (EmployeeDocumentUpload?employeeId=4430&fiscalPeriodId=3:90:11) at init.trigger (kendo.all.js:164:37) at init._click (kendo.all.js:30687:54) at HTMLSpanElement.i (jquery.min.js:2:87485)
服务器端代码(ASP.NET Core)
public JsonResult OnPostFileUpload(IFormFile employeeDocumentFile, int employeeId, int fiscalPeriodId) { bool isSuccess = DLStatement.SaveEmployeeDocument(employeeDocumentFile, employeeId, fiscalPeriodId, User.Identity.Name); return new JsonResult(new { success = isSuccess }); }
已尝试但未成功的方案
- 使用FormData对象,但出现400错误或服务器端IFormFile为null:
var fileData = null; function onSelect(e) { fileData = e.files[0]; } // onClickUploadEmployeeDocument中的代码片段 var formData = new FormData(); formData.append('employeeDocumentFile', fileData); formData.append('employeeId', $("#EmployeeId").val()); formData.append('fiscalPeriodId', $("#FiscalPeriodId").val()); $.ajax({ type: "POST", url: _url, data: formData, headers: { "RequestVerificationToken": $('input[name="__RequestVerificationToken"]').val() }, processData: false, contentType: false, success: function (response) { if (response.success) { window.parent.$("#employeeFileUploadWnd").data("kendoWindow").close(); window.parent.rebindEmployeeDocumentsGrid(); } }, error: function (xhr, textStatus, errorThrown) { } });
- 直接提交表单,但仅刷新页面,未请求到服务器:
<form id="formEmployeeDocument" class="ct-small-popup__form" method="POST"> <div class="ct-small-popup__field-container"> <div class="ct-small-popup__field ct-small-popup__field--width100 ct-small-popup__field--flex-column"> <div class="ct-small-popup__field-information-container ct-small-popup__field-information-container--width365"> @(Html.Kendo().Upload() .Name("employeeDocument") .Messages(m => m.Select("Select")) .Multiple(false) .Events(e => e.Select("onSelect")) .Validation(validatoin => validatoin.AllowedExtensions(new string[] { ".jpeg", ".jpg", ".png", ".doc", ".docx", ".xls", ".xlsx", ".pdf", ".htm", ".html", ".eml", ".msg" })) ) </div> </div> </div> <input type="submit" value="Upload" id="hidUpload" style="display:none" /> </form>
function onClickUploadEmployeeDocument(e) { $('#hidUpload').click(); }
正确解决方案
客户端AJAX修正方案
问题核心是Kendo Upload返回的e.files[0]是封装后的对象,需取rawFile属性获取原生File对象,同时确保FormData和AJAX配置正确:
var fileData = null; function onSelect(e) { // 获取原生File对象 fileData = e.files[0].rawFile; } function onClickUploadEmployeeDocument(e) { var formData = new FormData(); // 追加文件 formData.append('employeeDocumentFile', fileData); // 追加额外参数 formData.append('employeeId', $("#EmployeeId").val()); formData.append('fiscalPeriodId', $("#FiscalPeriodId").val()); var _url = "/Statement/EmployeeDocumentUpload?handler=FileUpload"; $.ajax({ type: "POST", url: _url, data: formData, // 禁止jQuery处理FormData,避免编码错误 processData: false, contentType: false, headers: { "RequestVerificationToken": $('input[name="__RequestVerificationToken"]').val() }, success: function (response) { if (response.success) { window.parent.$("#employeeFileUploadWnd").data("kendoWindow").close(); window.parent.rebindEmployeeDocumentsGrid(); } }, error: function (xhr, textStatus, errorThrown) { console.error(xhr.responseText); } }); }
表单提交修正方案(可选)
若选择表单提交,需设置正确的enctype、匹配参数名并包含防伪令牌:
<form id="formEmployeeDocument" class="ct-small-popup__form" method="POST" asp-page-handler="FileUpload" enctype="multipart/form-data"> @Html.AntiForgeryToken() <!-- 隐藏域传递额外参数 --> <input type="hidden" id="EmployeeId" name="employeeId" value="@Model.EmployeeId" /> <input type="hidden" id="FiscalPeriodId" name="fiscalPeriodId" value="@Model.FiscalPeriodId" /> <div class="ct-small-popup__field-container"> <div class="ct-small-popup__field ct-small-popup__field--width100 ct-small-popup__field--flex-column"> <div class="ct-small-popup__field-information-container ct-small-popup__field-information-container--width365"> @(Html.Kendo().Upload() .Name("employeeDocumentFile") <!-- 与服务器端参数名一致 --> .Messages(m => m.Select("Select")) .Multiple(false) .Validation(validatoin => validatoin.AllowedExtensions(new string[] { ".jpeg", ".jpg", ".png", ".doc", ".docx", ".xls", ".xlsx", ".pdf", ".htm", ".html", ".eml", ".msg" })) ) </div> </div> </div> <input type="submit" value="Upload" id="hidUpload" style="display:none" /> </form>
function onClickUploadEmployeeDocument(e) { $('#formEmployeeDocument').submit(); }
关键注意事项
- Kendo Upload的
e.files返回封装对象,必须用rawFile获取原生File对象才能存入FormData。 - AJAX上传时必须设置
processData: false和contentType: false,防止jQuery自动编码数据或设置错误的请求头。 - 表单提交时必须设置
enctype="multipart/form-data",且控件Name需与服务器端参数名完全匹配,同时包含AntiForgeryToken。
内容的提问来源于stack exchange,提问作者Legion
相关产品推荐
相关产品推荐

