ASP.NET中AJAX传递IFormFile与字符串参数均为null的问题
版本信息
- ASP.NET and Web Tools - 17.10.341.11210
- C# Tools - 4.10.0-3.24312.19+
- JQuery - 3.3.1.js
- JS - 2.8.3.js
问题描述
我尝试从文件选择组件和字符串输入框向C#后端方法传递IFormFile和字符串参数。单独测试时,文件选择和字符串输入都能正确获取对应值,但将两者一起传递时,C#方法中的两个参数均为null。
相关代码
HTML代码
<div class="text-center"> <h1 class="display-4">Validation</h1> <p> <label for="string" style="margin: 5px">String Validation?</label> <br /> <input type="email" id="string" name="string" value="email@email.com" style="margin:5px;"> <br /> </p> </div> <div class="text-center"> <label for="fileSelection" style="margin: 5px">Please select which file you would like to validate.</label> <br /> <span id="csvOnly" class="uploadErrorMsg">Only CSV files are able to be uploaded</span> <br /> <input type="file" id="fileSelection" name="fileSelection" accept=".csv, text/csv" /> <br /> <button id="btnValidate" onclick="btnValidate()">Validate</button> <!--onclick="btnUpload_Click()" name="btnUpload" --> <br /> <label id="lblError"></label> </div>
JavaScript代码
function btnValidate() { input = document.getElementById('fileSelection'); file = input.files[0]; fileName = file.name; fileName = fileName.toUpperCase(); //alert("file = " + file.name); //good var stringSelection = document.getElementById('string').value; //alert("string is = " + stringSelection); //good if (fileName.includes('CSV')) { //alert("string is = " + stringSelection); //good var data = new FormData(); file = input.files[0]; data.append("File", file); console.log(data); //alert("file = " + data.values); //var parameters = { file: data, inputString: stringSelection }; //alert("parameters = " + parameters.inputString" " + parameters.file); //bad //alert("parameters = " + parameters.file.value); //good $.ajax({ type: "POST", url: "@Url.Content("~/Validation/UploadFile")", dataType: 'json', contentType: false, processData: false, data: { file:data, inputString: stringSelection}, //other things I've tried //JSON.stringify({ file: data, inputString: 'stringSelection' }), //'{ "file":' + data + ', "inputString": "stringSelection" }', //JSON.stringify({ parameters }), //{parameters}, success: function(data){ return result; }, error: function (xhr, status, error) { alert("error message " + error + " " + status); } }); } }
C#代码
public JsonResult UploadPayrollFile(IFormFile file, string stringSelection) { //do stuff //I setup a breakpoint here to check to see what information is coming in, both parameters are coming in null. //When I adjust the method to check for a singular parameter, they work (separately) }
排查情况
已参考Stack Overflow相关问题的解决方案,但均无效,程序可正常运行无报错。
解决方案
问题核心在于AJAX请求的参数传递方式错误:不能将FormData嵌套在普通对象中传递,需把所有参数(文件+字符串)都添加到同一个FormData实例,同时保证前后端参数名称完全匹配。
1. 修改JavaScript代码
将字符串参数也追加到FormData中,直接传递该实例:
function btnValidate() { input = document.getElementById('fileSelection'); file = input.files[0]; fileName = file.name; fileName = fileName.toUpperCase(); var stringSelection = document.getElementById('string').value; if (fileName.includes('CSV')) { var data = new FormData(); // 键名需和后端方法参数名完全一致 data.append("file", file); data.append("stringSelection", stringSelection); $.ajax({ type: "POST", url: "@Url.Content("~/Validation/UploadFile")", dataType: 'json', contentType: false, processData: false, data: data, // 直接传递FormData对象 success: function(response){ console.log(response); }, error: function (xhr, status, error) { alert("error message " + error + " " + status); } }); } }
2. 确认后端方法参数名
你的现有C#代码参数名已经和FormData中的键名匹配,无需修改:
public JsonResult UploadPayrollFile(IFormFile file, string stringSelection) { // 此时参数可正常获取值 if (file != null && !string.IsNullOrEmpty(stringSelection)) { // 业务逻辑处理 } return Json(new { success = true }); }
关键注意点
contentType: false和processData: false必须保留,这是正确传递FormData的核心配置。- 不要用
JSON.stringify处理FormData,它是二进制表单格式,无法直接序列化为JSON。
内容的提问来源于stack exchange,提问作者Kevin Fischer
相关产品推荐
相关产品推荐

