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

为BeginForm添加onsubmit后Request.files为空,移除则正常

问题原因分析

你遇到的核心问题在于AJAX提交时没有正确处理文件数据:

  • 当你添加onsubmit="return SubmitForm(this)"后,表单的默认同步提交被return false阻止,转而使用jQuery AJAX提交。
  • 但$(form).serialize()方法只能序列化文本类型的表单字段,完全不会处理<input type="file">控件的二进制文件数据,所以后端Request.Files自然返回null。
  • 移除onsubmit属性后,表单走浏览器默认的同步提交流程,浏览器会自动将文件数据打包进multipart/form-data请求中,因此后端能正常获取文件。
解决方案

根据你的需求(无刷新上传文件),可以修改AJAX提交逻辑,使用FormData对象来正确携带文件数据:

1. 修正前端JS代码

将SubmitForm函数修改为以下内容:

function SubmitForm(form) {
    $.validator.unobtrusive.parse(form);
    if ($(form).valid()) {
        // 创建FormData对象,自动包含表单所有数据(包括文件)
        const formData = new FormData(form);
        
        $.ajax({
            type: "POST",
            url: form.action,
            data: formData,
            // 必须设置这两个属性,禁止jQuery处理数据和修改Content-Type
            processData: false,
            contentType: false,
            success: function (data) {
                if (data.success) {
                    Popup.dialog('close');
                    dataTable.ajax.reload();
                    $.notify(data.message, {
                        globalPosition: "top center",
                        className: "success"
                    })
                }
            }
        });
    }
    return false;
}

2. 后端Action适配

你可以选择两种方式接收文件:

方式1:直接通过Request.Files获取

[HttpPost]
public ActionResult Create(Model model)
{
    // 获取上传的文件(name属性为"file")
    var uploadFile = Request.Files["file"];
    if (uploadFile != null && uploadFile.ContentLength > 0)
    {
        // 示例:保存文件到服务器指定目录
        var fileName = Path.GetFileName(uploadFile.FileName);
        var savePath = Path.Combine(Server.MapPath("~/Uploads"), fileName);
        uploadFile.SaveAs(savePath);
    }
    
    // 其他业务逻辑
    return Json(new { success = true, message = "创建成功" });
}

方式2:直接接收HttpPostedFileBase参数

如果是单个文件,可直接在Action参数中声明(参数名需与input的name一致):

[HttpPost]
public ActionResult Create(Model model, HttpPostedFileBase file)
{
    if (file != null && file.ContentLength > 0)
    {
        // 处理文件逻辑
    }
    
    return Json(new { success = true, message = "创建成功" });
}

如果是多文件上传(你的input设置了multiple="multiple"),可以用IEnumerable<HttpPostedFileBase>:

[HttpPost]
public ActionResult Create(Model model, IEnumerable<HttpPostedFileBase> file)
{
    foreach (var f in file)
    {
        if (f != null && f.ContentLength > 0)
        {
            // 逐个处理文件
        }
    }
    
    return Json(new { success = true, message = "创建成功" });
}

3. 关键注意事项

  • 表单的enctype="multipart/form-data"必须保留,这是文件上传的必要前提。
  • 使用FormData时,必须设置processData: false和contentType: false,否则jQuery会将FormData转换为字符串,导致文件上传失败。
备选方案(放弃无刷新上传)

如果你不需要无刷新提交,可以简化JS逻辑,让表单走默认同步提交:

function SubmitForm(form) {
    $.validator.unobtrusive.parse(form);
    // 验证通过就允许默认提交,不通过则阻止
    return $(form).valid();
}

这种方式下后端无需修改,和你移除onsubmit属性时的逻辑一致,但页面会刷新。

内容的提问来源于stack exchange,提问作者marwen1

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 21:37:56