使用Mailkit发送非TXT附件损坏问题求助(C#)
问题根源
你的代码用文本流(StreamReader/StreamWriter)处理所有类型附件,这会导致二进制文件(jpg、pdf、zip等)损坏:文本流会尝试将字节转换为字符编码,过程中会丢失或篡改二进制数据,只有纯文本文件(如TXT)能正常处理。
另外,你在添加附件后立即删除临时文件,可能导致MailKit还没完成文件读取就丢失源文件,引发异常或不完整附件。
解决方案
拆分逻辑:仅对文本文件做内容替换,二进制文件直接复制字节流;同时延迟删除临时文件到邮件发送完成后。
修改后的附件处理方法
private string ProcessAttachment(string filePath, string recipientemail, string senderemail, string sendername, string newFileName) { Replacer replacer = new Replacer(); // 先替换文件名中的变量 string tempFileName = replacer.DoReplace(newFileName, recipientemail, senderemail, sendername); string tempFile = Path.Combine(Helpers.tempPath, tempFileName); // 定义需要做内容替换的文本文件扩展名(可根据需求调整) var textFileExtensions = new HashSet<string> { ".txt", ".log", ".csv", ".md" }; string fileExt = Path.GetExtension(filePath).ToLowerInvariant(); if (textFileExtensions.Contains(fileExt)) { // 文本文件:读取内容并替换变量后写入临时文件 string content; using (StreamReader sr = File.OpenText(filePath)) { content = sr.ReadToEnd(); content = replacer.DoReplace(content, recipientemail, senderemail, sendername); } using (var tw = new StreamWriter(tempFile, false, Encoding.UTF8)) { tw.Write(content); } } else { // 二进制文件:直接复制原文件字节,避免编码转换损坏数据 File.Copy(filePath, tempFile, overwrite: true); } return tempFile; }
修改附件添加与临时文件删除逻辑
// 存储临时文件路径,等待发送完成后删除 var tempAttachmentPaths = new List<string>(); foreach (var attachment in letter.attachment) { string newAttachment = ProcessAttachment(attachment.filePath, recipientData.email, senderData.senderEmail, senderData.senderName, attachment.fileName); bodyBuilder.Attachments.Add(newAttachment); tempAttachmentPaths.Add(newAttachment); Console.WriteLine(newAttachment); } // --- 此处执行邮件发送逻辑 --- using (var smtpClient = new SmtpClient()) { smtpClient.Connect("smtp.yourserver.com", 587, SecureSocketOptions.StartTls); smtpClient.Authenticate("your-account", "your-password"); smtpClient.Send(yourMimeMessage); smtpClient.Disconnect(true); } // 邮件发送完成后,删除所有临时文件 foreach (var tempPath in tempAttachmentPaths) { try { File.Delete(tempPath); } catch (Exception ex) { Console.WriteLine($"删除临时文件失败 {tempPath}:{ex.Message}"); } }
关键说明
- 二进制文件处理:用
File.Copy直接复制字节流,完全保留原文件的二进制数据,避免编码转换导致的损坏。 - 文本文件范围控制:通过扩展名列表明确哪些文件需要做内容替换,避免误处理二进制文件。
- 临时文件生命周期:必须等邮件发送完成后再删除临时文件,确保MailKit有足够时间读取附件内容。
内容的提问来源于stack exchange,提问作者Oleg Buga
相关产品推荐
相关产品推荐

