You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 12:17:55