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

Exchange EmailAttachment转SMTP MailAttachment后.msg附件显示异常的解决咨询

问题

将Microsoft Exchange的EmailMessage转换为MailMessage通过SMTP发送邮件时,.docx、.txt、.jpg等普通附件显示正常,但包含.msg格式的邮件附件转换后,SMTP附件会变成乱码/流形式。需要修改代码,让.msg附件与Exchange原附件完全一致。

当前代码

MailMessage message = new MailMessage();
EmailMessage msg = new EmailMessage(service); //service is Microsoft.Exchange.WebServices.Data
MemoryStream ms = new MemoryStream();
            
PropertySet propSet = new PropertySet(BasePropertySet.FirstClassProperties,ItemSchema.Attachments, EmailMessageSchema.NormalizedBody, EmailMessageSchema.TextBody);
propSet.RequestedBodyType = BodyType.HTML;
propSet.BlockExternalImages = false;
msg = EmailMessage.Bind(service, emailId, propSet);

foreach (Microsoft.Exchange.WebServices.Data.Attachment attachment in msg.Attachments){  
    if (attachment is FileAttachment)
    {
        // Attachments such as .txt, .docx, .xlsx
        // This code block for FileAttachment is totally working fine.
        FileAttachment fileAttachment = attachment as FileAttachment;
        if (fileAttachment != null)
        {
            fileAttachment.Load();
            ms = new MemoryStream(fileAttachment.Content);
            attachmentName = fileAttachment.Name;
            System.Net.Mail.Attachment att = new System.Net.Mail.Attachment(ms, attachmentName);
            message.Attachments.Add(att);
        }
    }
    else if (attachment is ItemAttachment)
    {
        //This is where the EmailMessage attachment gets converted to MailMessage attachment
        //Attachment is .msg
        //The result here becomes random strings
        ItemAttachment itemAttachment = attachment as ItemAttachment;
        if (itemAttachment != null)
        {
             itemAttachment.Load(new PropertySet(ItemSchema.MimeContent));
             byte[] itemContent = itemAttachment.Item.MimeContent.Content.ToArray();
             ms = new MemoryStream(itemContent);
             attachmentName = itemAttachment.Name;
             System.Net.Mail.Attachment att = new System.Net.Mail.Attachment(ms, attachmentName, attachment.ContentType);
             message.Attachments.Add(att);
        }
    }
}

//Send the MailMessage using SMTP
using (SmtpClient client = new SmtpClient())
{
    client.Host = config.smtp_AmazonAWSHost;
    client.Port = config.portSMTP;
    client.UseDefaultCredentials = false;
    client.Credentials = new NetworkCredential(config.smtp_Username, config.smtp_Password);
    client.EnableSsl = true;
    client.Send(message);
}

解决方案

问题出在处理.msg附件的逻辑里:你当前读取的是邮件的MimeContent(MIME格式的文本内容),而不是Outlook .msg文件的二进制格式。要导出真正的.msg文件,需要将ItemAttachment保存为MSG格式的流。

修改ItemAttachment分支的代码如下:

else if (attachment is ItemAttachment)
{
    ItemAttachment itemAttachment = attachment as ItemAttachment;
    if (itemAttachment != null)
    {
        // 加载完整的Item对象,不需要指定PropertySet为MimeContent
        itemAttachment.Load();
        ms = new MemoryStream();
        // 将Item保存为MSG格式到流中
        itemAttachment.Item.Save(ms, SaveFormat.Msg);
        // 重置流的位置到起始处,确保读取完整内容
        ms.Position = 0;
        attachmentName = itemAttachment.Name;
        // 指定.msg文件的标准MIME类型
        System.Net.Mail.Attachment att = new System.Net.Mail.Attachment(ms, attachmentName, "application/vnd.ms-outlook");
        message.Attachments.Add(att);
    }
}

关键修改点

  1. 移除ItemSchema.MimeContent的加载逻辑,改为加载完整的Item对象
  2. 使用Item.Save(Stream, SaveFormat.Msg)将邮件附件导出为标准的.msg二进制流
  3. 重置流的位置到起始处,避免读取时跳过内容
  4. 指定附件的ContentType为application/vnd.ms-outlook,这是.msg文件的官方MIME类型

这样处理后,SMTP发送的.msg附件就会和Exchange原附件完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 19:42:09