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); } }
关键修改点
- 移除
ItemSchema.MimeContent的加载逻辑,改为加载完整的Item对象 - 使用
Item.Save(Stream, SaveFormat.Msg)将邮件附件导出为标准的.msg二进制流 - 重置流的位置到起始处,避免读取时跳过内容
- 指定附件的ContentType为
application/vnd.ms-outlook,这是.msg文件的官方MIME类型
这样处理后,SMTP发送的.msg附件就会和Exchange原附件完全一致。
内容的提问来源于stack exchange,提问作者Ian Jasper
相关产品推荐
相关产品推荐

