.NET Core 7多文件上传问题:表单文件无法传递至控制器
多文件上传嵌套DTO文件无法传递到.NET Core 7控制器问题
我基于.NET Core 7开发,现有一个多文件上传表单,通过嵌套DTO类(OrganisationRegDto和RegAttachedDto)传递文件及关联数据,数据行数不固定。目前其他数据能正常传到控制器,但文件无法传递,尝试过多种操作仍未解决。
后端DTO类
public class RegAttachedDto { public int? DocumentTypeId { get; set; } public string? Name { get; set; } public IFormFile? RegFIleFile { get; set; } } public class OrganisationRegDto { public int RegistrationId { get; set; } public string Name { get; set; } = null!; public int RegdCategoryId { get; set; } public double AuthorizedCapital { get; set; } public double PaidupCapital { get; set; } public double IssuedCapital { get; set; } public bool IsAssociateMember { get; set; } public IList<RegAttachedDto> regAttachedDtos { get; set; } }
前端JS代码
let regAttachedDtosArr = new Array(); let regAttachedDtosfn = () => { $('#businessRegDocument .trdata').each(function (i, row) { let DocumentTypeId = $(this).find("td .DocumentTypeId").val(); let RegFIleFile = $(this).find("td .DocTypeName")[0].files[0]; let DocDescription = $(this).find("td .DocDescription").val(); if (RegFIleFile != 'undefined' && DocumentTypeId != '' && DocDescription != '') { regAttachedDtosArr.push({ RegFIleFile: RegFIleFile, DocumentTypeId: DocumentTypeId, DocDescription: DocDescription }); } }); } let SendToDb = () => { regAttachedDtosArr = []; regAttachedDtosfn(); let formdata = new FormData(); formdata.append("Name", $("#Name").val()); formdata.append("RegdCategoryId", $("#RegdCategoryId").val()); formdata.append("AuthorizedCapital", $("#AuthorizedCapital").val()); formdata.append("PaidupCapital", $("#PaidupCapital").val()); formdata.append("IssuedCapital", $("#IssuedCapital").val()); formdata.append("IsAssociateMember", $("#IsAssociateMember").is(':checked')); formdata.append("regAttachedDtos", JSON.stringify(regAttachedDtosArr)); console.log(regAttachedDtosArr); // 文件在此控制台可见 console.log(formdata); $.ajax({ url: '/Controllername/actionName', type: 'POST', contentType: false, processData: false, data: formdata }).done((res) => { toastr.success("Success", { timeOut: 8000 }); }).catch((ex) => { toastr.error(ex); }); }, function () { }); } $('#regorgForm').submit(function (e) { e.preventDefault(); SendToDb(); });
后端控制器代码
public IActionResult actionName([FromForm]OrganisationRegDto regDto) { var regAttachedFiles = HttpContext.Request.Form["regAttachedDtos"]; var boardMember = HttpContext.Request.Form["boardMemberDtos"]; var regAuthority = HttpContext.Request.Form["regAuthorityDtos"]; var files = HttpContext.Request.Form.Files; // 此处文件数量为0 return View("Index"); }
已尝试操作
- 设置请求类型为multipart
- 添加/移除
JSON.stringify处理嵌套DTO数组 - 调整
contentType与processData参数
解决方案
问题根源:JSON.stringify无法序列化File对象,把包含文件的数组转成JSON后,文件信息会丢失,导致后端无法接收。需修改前端FormData的构建方式,让.NET Core模型绑定器正确识别嵌套集合和文件。
1. 修改前端SendToDb函数
let SendToDb = () => { regAttachedDtosArr = []; regAttachedDtosfn(); let formdata = new FormData(); // 添加主DTO字段 formdata.append("Name", $("#Name").val()); formdata.append("RegdCategoryId", $("#RegdCategoryId").val()); formdata.append("AuthorizedCapital", $("#AuthorizedCapital").val()); formdata.append("PaidupCapital", $("#PaidupCapital").val()); formdata.append("IssuedCapital", $("#IssuedCapital").val()); formdata.append("IsAssociateMember", $("#IsAssociateMember").is(':checked')); // 逐个添加嵌套的RegAttachedDto数据和文件,使用索引格式让模型绑定识别 regAttachedDtosArr.forEach((item, index) => { formdata.append(`regAttachedDtos[${index}].DocumentTypeId`, item.DocumentTypeId); formdata.append(`regAttachedDtos[${index}].Name`, item.DocDescription); // 对应DTO的Name字段 if (item.RegFIleFile) { formdata.append(`regAttachedDtos[${index}].RegFIleFile`, item.RegFIleFile); } }); $.ajax({ url: '/Controllername/actionName', type: 'POST', contentType: false, processData: false, data: formdata }).done((res) => { toastr.success("Success", { timeOut: 8000 }); }).catch((ex) => { toastr.error(ex); }); }
2. 简化后端控制器代码
无需手动读取Form,[FromForm]会自动完成嵌套DTO和文件的绑定:
public IActionResult actionName([FromForm]OrganisationRegDto regDto) { // 直接遍历嵌套的DTO集合处理文件 foreach(var attachedDto in regDto.regAttachedDtos) { if(attachedDto.RegFIleFile != null) { // 示例:获取文件名 var fileName = attachedDto.RegFIleFile.FileName; // 执行文件保存等逻辑 } } return View("Index"); }
内容的提问来源于stack exchange,提问作者Kamal Timalsina
相关产品推荐
相关产品推荐

