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

ASP.NET MVC中通过JQuery AJAX上传Excel后MyController2无法获取文件如何解决

问题原因

你碰到的问题由两个错误导致:

  1. 发送邀请的AJAX请求写法错误:无法通过JSON序列化传输二进制文件,所以MyController2里Request.Files.Count为0
  2. HttpPostedFileBase对象和当前请求的输入流绑定,请求结束后流会被自动释放,直接存到TempData里下次读取必然拿不到有效内容,这就是你看到ContentLength为0的原因

解决方案

这里提供两种可行方案,按需选择即可:

方案1:发送邀请时直接传文件(推荐,逻辑更简单)

修改前端SendInvite方法,不要把参数转成JSON,把表单字段和文件都放到FormData里传输,配置和之前上传校验的AJAX保持一致:

function SendInvite() {
  // 先完成页面其他输入项校验
  var formData = new FormData();
  // 追加Excel文件
  var excelFile = document.getElementById('ExcelFile');
  if (excelFile.files.length > 0) {
    formData.append('excelFile', excelFile.files[0]);
  }
  // 追加MyModel的所有字段,示例:假设MyModel有Title、Contact两个字段
  formData.append('myModel.Title', $('#titleInput').val());
  formData.append('myModel.Contact', $('#contactInput').val());

  $.ajax({
    type: "POST",
    url: "你的MyController2接口地址",
    data: formData,
    contentType: false, // 必须设为false,让浏览器自动设置正确的请求头
    processData: false, // 必须设为false,不要让Jquery处理FormData
    dataType: "json",
    success: function (data) {
      // 成功处理逻辑
    },
    error: function (data) {
      // 错误处理逻辑
    }
  });
}

修改后MyController2可以直接拿到文件:

public JsonResult MyController2(MyModel myModel, HttpPostedFileBase excelFile)
{
    // 这里excelFile已经可以正常读取,Request.Files也有值
    // 后续发邮件等逻辑
}

方案2:校验后存储文件字节到TempData(适合需要保留校验结果的场景)

不要直接存HttpPostedFileBase,把文件转成字节数组存储到TempData,读取时直接用字节数组即可:

第一步:修改校验接口的存储逻辑

[HttpPost]
public JsonResult MyController(HttpPostedFileBase excelFile)
{
 if (Request.Files.Count > 0)
 {
   excelFile = Request.Files[0];    
   var result = // 你的文件校验逻辑
   if(result.校验成功)
   {
       // 把文件流转成字节数组存储
       using (var reader = new BinaryReader(excelFile.InputStream))
       {
           TempData["ExcelBytes"] = reader.ReadBytes(excelFile.ContentLength);
       }
       // 额外存储文件名、格式,后续发附件会用到
       TempData["ExcelFileName"] = excelFile.FileName;
       TempData["ExcelContentType"] = excelFile.ContentType;
   }
   return Json(result);
 }     
  return null;
}

第二步:修改发送邀请接口的读取逻辑

public JsonResult MyController2(MyModel myModel)
{
    byte[] excelBytes = TempData["ExcelBytes"] as byte[];
    string fileName = TempData["ExcelFileName"] as string;
    string contentType = TempData["ExcelContentType"] as string;
    
    if(excelBytes != null && excelBytes.Length > 0)
    {
        // 这里已经拿到完整的Excel文件内容,发邮件时直接把这个字节数组作为附件即可
    }
    // 后续业务逻辑
}

注意事项

  • TempData默认读取一次后就会被销毁,如果需要多次读取可以调用TempData.Keep("ExcelBytes")保留数据
  • 如果Excel文件比较大,建议校验后先存到服务器临时目录,把路径存到TempData,发完邮件再删除临时文件,避免占用服务端内存

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 13:06:04