You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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}");
    }
}
关键说明
  1. 二进制文件处理:用File.Copy直接复制字节流,完全保留原文件的二进制数据,避免编码转换导致的损坏。
  2. 文本文件范围控制:通过扩展名列表明确哪些文件需要做内容替换,避免误处理二进制文件。
  3. 临时文件生命周期:必须等邮件发送完成后再删除临时文件,确保MailKit有足够时间读取附件内容。

内容的提问来源于stack exchange,提问作者Oleg Buga

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 08:43:39