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

启用微软反垃圾邮件后,MailKit解析Office365已读回执问题

解决MailKit解析Office365邮件的两个问题

一、找回反垃圾邮件转发后的原始EML附件

Office365反垃圾邮件处理后,原始外部邮件可能不会被归入Attachments集合(默认仅识别Content-Disposition为attachment的部分),而是嵌套在MIME结构的深层节点中。需递归遍历所有MIME实体来定位:

  1. 递归遍历MIME结构
    编写方法筛选出message/rfc822类型(原始邮件标准类型)或后缀为.eml的application/octet-stream类型部分:

    private static List<MimePart> FindRawEmailParts(MimeEntity entity)
    {
        var targetParts = new List<MimePart>();
        
        if (entity is MimePart part)
        {
            bool isRawEmail = part.ContentType.MimeType == "message/rfc822" || 
                            (part.ContentType.MimeType == "application/octet-stream" && 
                             part.FileName?.EndsWith(".eml", StringComparison.OrdinalIgnoreCase) == true);
            if (isRawEmail) targetParts.Add(part);
        }
        else if (entity is Multipart multipart)
        {
            foreach (var subEntity in multipart)
            {
                targetParts.AddRange(FindRawEmailParts(subEntity));
            }
        }
        
        return targetParts;
    }
    
  2. 提取并加载原始邮件
    获取邮件后调用上述方法,将找到的部分加载为MimeMessage:

    var rawEmailParts = FindRawEmailParts(loadedMessage);
    foreach (var part in rawEmailParts)
    {
        using (var stream = part.ContentObject.Open())
        {
            var originalMessage = MimeMessage.Load(stream);
            // 处理原始邮件逻辑
        }
    }
    

二、解析已读回执的原始邮件及Message-ID

已读回执的顶级MIME类型为message/disposition-notification,其中嵌套的message/rfc822部分是原始邮件。解决加载空消息和无法访问私有属性的问题:

  1. 识别已读回执
    通过MIME类型判断最可靠:

    bool IsReadReceipt(MimeMessage message)
    {
        return message.ContentType.MimeType == "message/disposition-notification";
    }
    
  2. 正确加载嵌套的原始邮件
    避免使用WriteTo,直接通过ContentObject获取流加载:

    if (IsReadReceipt(loadedMessage))
    {
        if (loadedMessage.Body is Multipart multipart)
        {
            foreach (var entity in multipart)
            {
                if (entity is MimePart part && part.ContentType.MimeType == "message/rfc822")
                {
                    using (var stream = part.ContentObject.Open())
                    {
                        var originalMessage = MimeMessage.Load(stream);
                        // 获取原始邮件的Message-ID
                        string originalMsgId = originalMessage.MessageId;
                        // 后续处理逻辑
                    }
                }
            }
        }
    }
    
  3. 兜底方案:直接解码内容
    若流加载仍为空,可尝试直接解码部分内容后解析:

    var rawContent = part.ContentObject.DecodeToString();
    using (var reader = new StringReader(rawContent))
    {
        var originalMessage = MimeMessage.Load(reader);
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 06:18:20