本地正常服务器报错:Asp.Net读取IFormFile时流复制异常
问题:读取XLSX文件更新数据库时服务器报错(本地运行正常)
错误信息
{ "error": "Error while copying content to a stream.", "exceptionType": "System.Net.Http.HttpRequestException", "innerException": "Cannot access a disposed object.\r\nObject name: 'System.Net.Http.StreamContent'.", "stackTrace": " at System.Net.Http.HttpContent.CheckDisposed()\r\n" }
代码实现
[RequestFormLimits(MultipartBodyLengthLimit = 52428800, ValueLengthLimit = 52428800)] public async Task<IActionResult> ImportSheet([FromForm] IFormFile uploadedFile) { var isClean = await _antimalwareScanService.PostSingleFileResponseAsync(uploadedFile); if (isClean) { if (uploadedFile is null) { return BadRequest(); } if (!string.IsNullOrEmpty(uploadedFile.FileName)) { using var stream = uploadedFile.OpenReadStream(); //using var memoryStream = new MemoryStream(); //await stream.CopyToAsync(memoryStream); using ExcelPackage excel = new(stream); ExcelPackage.LicenseContext = LicenseContext.NonCommercial; ExcelWorkbook workbook = excel.Workbook; ExcelWorksheets worksheets = workbook.Worksheets; var psWorksheets = worksheets.FirstOrDefault(x => x.Name.ToLower().Contains("prof services")); if (psWorksheets != null) { await _fileViewModelService.UploadProfServicesFile(psWorksheets); } stream.Dispose(); } } return Ok(); }
问题分析与解决方案
手动调用
stream.Dispose()是冗余操作:stream通过using声明,会在代码块结束时自动释放资源。提前手动释放会导致后续ExcelPackage内部可能的流访问操作触发已释放对象异常,直接移除该调用即可。服务器环境下反病毒扫描可能消耗了原文件流:本地环境的扫描逻辑可能未完全读取
IFormFile的流,但服务器端扫描服务PostSingleFileResponseAsync可能已经读取并消耗了原流,导致后续打开的流无法正常使用。解决方案是提前将文件内容复制到内存流,避免原流被消耗:[RequestFormLimits(MultipartBodyLengthLimit = 52428800, ValueLengthLimit = 52428800)] public async Task<IActionResult> ImportSheet([FromForm] IFormFile uploadedFile) { if (uploadedFile is null || string.IsNullOrEmpty(uploadedFile.FileName)) { return BadRequest(); } // 先将文件复制到内存流保存 using var memoryStream = new MemoryStream(); await uploadedFile.CopyToAsync(memoryStream); memoryStream.Position = 0; // 创建新的IFormFile用于扫描,避免原流被消耗 var scannedFile = new FormFile(memoryStream, 0, memoryStream.Length, uploadedFile.Name, uploadedFile.FileName); var isClean = await _antimalwareScanService.PostSingleFileResponseAsync(scannedFile); if (isClean) { // 重置内存流位置,供ExcelPackage读取 memoryStream.Position = 0; using ExcelPackage excel = new(memoryStream); ExcelPackage.LicenseContext = LicenseContext.NonCommercial; ExcelWorkbook workbook = excel.Workbook; ExcelWorksheets worksheets = workbook.Worksheets; var psWorksheets = worksheets.FirstOrDefault(x => x.Name.ToLower().Contains("prof services")); if (psWorksheets != null) { await _fileViewModelService.UploadProfServicesFile(psWorksheets); } } return Ok(); }
内容的提问来源于stack exchange,提问作者Sabri Baazaoui
相关产品推荐
相关产品推荐

