ASP.NET Core 7 MVC文件上传时出现FileNotFound异常如何解决?
解决ASP.NET Core 7 MVC文件上传中的FileNotFoundException问题
问题根源在于你错误地尝试通过客户端文件名读取服务器本地文件:File.ReadAllText(fileName)会在服务器的应用目录下查找对应文件名的文件,而上传的文件实际是存在于HTTP请求的流中,并没有被保存到服务器本地。attachmentItem.FileName只是客户端上传时的文件名,不是服务器上的有效路径。
正确处理IFormFile的方式
直接从IFormFile的OpenReadStream()方法获取文件流,读取其中的内容,无需依赖本地文件系统:
修改邮件服务中的附件处理代码:
public async Task<bool> SendMailAsync(string template, string name, string email, string subject, string msg, [Optional] IList<IFormFile> attachment) { try { // ... 其他原有代码 if (attachment != null) { this.logger.LogInformation("Attempting to send mail via SendGrid with attachment"); foreach (var attachmentItem in attachment) { string fileName = Path.GetFileName(attachmentItem.FileName); // 替换原错误代码,从IFormFile的流中读取字节 using (var memoryStream = new MemoryStream()) { await attachmentItem.CopyToAsync(memoryStream); byte[] byteData = memoryStream.ToArray(); mailMsg.Attachments = new List<Attachment> { new Attachment { Content = Convert.ToBase64String(byteData), Filename = fileName, Disposition = "attachment", }, }; } } } // ... 其他原有代码 } catch (Exception ex) { // 异常处理逻辑 this.logger.LogError(ex, "Failed to send email with attachment"); return false; } }
关键说明
- 避免使用本地文件路径:上传的
IFormFile是通过请求流传递的,不需要(也不应该)依赖服务器本地文件系统来读取内容。 - 使用异步流操作:
CopyToAsync是异步读取流的推荐方式,避免阻塞线程,符合ASP.NET Core的异步编程模型。 - 二进制文件处理:改用
MemoryStream读取原始字节,避免用Encoding.ASCII处理非文本文件(会导致文件损坏)。
可选扩展:如果需要先保存文件到服务器
如果业务需求需要先将上传文件保存到服务器本地,再读取处理,可以参考以下代码:
// 注入IWebHostEnvironment获取服务器存储目录 var uploadPath = Path.Combine(_webHostEnvironment.WebRootPath, "uploads"); Directory.CreateDirectory(uploadPath); var filePath = Path.Combine(uploadPath, fileName); using (var stream = new FileStream(filePath, FileMode.Create)) { await attachmentItem.CopyToAsync(stream); } // 从本地路径读取文件字节 byte[] byteData = File.ReadAllBytes(filePath);
注意:需确保服务器存储目录有写入权限,同时要设置文件清理策略,避免存储过多无用文件。
内容的提问来源于stack exchange,提问作者Sascha Manns
相关产品推荐
相关产品推荐

