C#模拟IFormFile读取Xlsx触发FileFormatException问题排查
问题解决:Mock IFormFile 读取xlsx时提示文件损坏
核心原因
你当前Mock的IFormFile存在两个关键问题:
- 用
StreamWriter写入的是纯文本CSV内容,但却将文件类型标记为xlsx格式。xlsx是基于XML的二进制压缩格式,并非纯文本,XLWorkbook(EPPlus)解析时会判定文件损坏。 - 创建FormFile后提前关闭了原始MemoryStream,后续读取流时会出现无法访问的问题(虽不是本次报错主因,但属于潜在bug)。
解决方案
方案一:使用真实测试xlsx文件生成Mock
将测试用的合法xlsx文件嵌入项目资源,读取其内容生成MemoryStream:
using System.Reflection; using Microsoft.AspNetCore.Http; public IFormFile CreateCorrectClientByFileMock() { var fileName = "test.xlsx"; // 替换为你的测试文件所在的嵌入资源命名空间 var assembly = Assembly.GetExecutingAssembly(); var resourceName = "YourProjectNamespace.Tests.test.xlsx"; using var resourceStream = assembly.GetManifestResourceStream(resourceName); var memoryStream = new MemoryStream(); resourceStream.CopyTo(memoryStream); memoryStream.Position = 0; return new FormFile(memoryStream, 0, memoryStream.Length, "id_from_form", fileName) { Headers = new HeaderDictionary(), ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }; }
方案二:用EPPlus直接生成合法xlsx流
利用你正在使用的EPPlus库,在代码中创建真实的xlsx文件流:
using Microsoft.AspNetCore.Http; using OfficeOpenXml; public IFormFile CreateCorrectClientByFileMock() { var fileName = "fileName.xlsx"; var memoryStream = new MemoryStream(); // 生成合法的xlsx文件内容 using (var wb = new XLWorkbook()) { var worksheet = wb.Worksheets.Add("Clients"); // 写入表头 worksheet.Cell(1, 1).Value = "name"; worksheet.Cell(1, 2).Value = "email"; worksheet.Cell(1, 3).Value = "date"; // 可选:添加测试数据 worksheet.Cell(2, 1).Value = "Test User"; worksheet.Cell(2, 2).Value = "test@example.com"; worksheet.Cell(2, 3).Value = DateTime.Now; wb.SaveAs(memoryStream); } memoryStream.Position = 0; return new FormFile(memoryStream, 0, memoryStream.Length, "id_from_form", fileName) { Headers = new HeaderDictionary(), ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }; }
额外注意点
- 不要提前关闭FormFile关联的MemoryStream,FormFile需要持有可读取的流实例,否则后续
OpenReadStream()会失败。 - 确保测试用的xlsx文件格式合法,避免因文件本身损坏导致测试失败。
内容的提问来源于stack exchange,提问作者Aline Oliveira
相关产品推荐
相关产品推荐

