通过Ajax从数据库下载文件时文件损坏或无法打开的问题排查
文件下载损坏的问题分析与修复方案
核心问题:未将文件实际内容写入数据库字段
你的上传接口代码中,仅初始化了taskListAttachment.Data的字节数组长度,但从未将上传文件的内容写入该数组。最终数据库中存储的Data字段是一个长度正确但内容全为0的空数组,下载时返回的是无效数据,导致所有类型的文件都损坏无法打开。
修复方案
修改上传接口的AddFile方法,补充读取文件内容到Data字段的逻辑,以下是两种可行方式:
方式一:从本地文件读取内容(适用于需要同时保存本地文件的场景)
[HttpPost] public IActionResult AddFile(IFormFile file, TaskListAttachment taskListAttachment) { if (file != null && file.Length > 0) { var fileName = Path.Combine("wwwroot/files", Path.GetFileName(file.FileName)); // 保存文件到本地 using (var stream = new FileStream(fileName, FileMode.Create)) { file.CopyTo(stream); } taskListAttachment.FileName = file.FileName; taskListAttachment.ContentType = file.ContentType; // 初始化字节数组并从本地文件读取内容 taskListAttachment.Data = new byte[file.Length]; using (var readStream = new FileStream(fileName, FileMode.Open)) { readStream.Read(taskListAttachment.Data, 0, (int)readStream.Length); } taskListAttachment.AddDateTime = DateTime.Now; taskListAttachment.FilePath = fileName; taskListAttachment.TaskId = Convert.ToInt32(Request.Form["TaskId"]); taskListAttachment.AddUserId = Convert.ToInt32(Request.Form["AddUserId"]); taskListAttachmentManager.itemAdd(taskListAttachment); var addValue = JsonConvert.SerializeObject(taskListAttachment); return Json(addValue); } else { return Json(null); } }
方式二:直接从上传流读取(更高效,避免二次IO)
如果不需要强制保存本地文件,或想优化性能,可以直接从IFormFile的流读取内容:
[HttpPost] public IActionResult AddFile(IFormFile file, TaskListAttachment taskListAttachment) { if (file != null && file.Length > 0) { var fileName = Path.Combine("wwwroot/files", Path.GetFileName(file.FileName)); // 用内存流中转,同时获取字节数组和保存到本地 using (var memoryStream = new MemoryStream()) { file.CopyTo(memoryStream); // 读取文件内容到Data字段 taskListAttachment.Data = memoryStream.ToArray(); // 保存到本地文件 memoryStream.Position = 0; using (var fileStream = new FileStream(fileName, FileMode.Create)) { memoryStream.CopyTo(fileStream); } } taskListAttachment.FileName = file.FileName; taskListAttachment.ContentType = file.ContentType; taskListAttachment.AddDateTime = DateTime.Now; taskListAttachment.FilePath = fileName; taskListAttachment.TaskId = Convert.ToInt32(Request.Form["TaskId"]); taskListAttachment.AddUserId = Convert.ToInt32(Request.Form["AddUserId"]); taskListAttachmentManager.itemAdd(taskListAttachment); var addValue = JsonConvert.SerializeObject(taskListAttachment); return Json(addValue); } else { return Json(null); } }
补充说明
- 你获取
TaskId和AddUserId的方式可以简化为Request.Form["TaskId"],逻辑更简洁; - 下载接口的代码本身没有问题,只要
Data字段存储了正确的文件字节内容,下载后文件即可正常打开。
内容的提问来源于stack exchange,提问作者Gökmen Ada
相关产品推荐
相关产品推荐

