You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何使用Microsoft Graph API将邮件转换为.msg格式并存储到本地?

解决方案:将MS Graph API获取的邮件转换为.msg文件存本地

嘿,我来帮你搞定把Graph API获取的邮件转成.msg文件的问题!MS Graph本身并不直接生成.msg格式,但我们可以通过两种靠谱的方式实现,结合你的现有代码来展开:

方案一:用开源MsgKit库生成.msg(跨平台友好)

MsgKit是专门处理.msg文件的.NET开源库,不需要依赖Outlook客户端,适合各种环境。

步骤1:安装依赖

先在项目里装NuGet包:

Install-Package MsgKit

或者用.NET CLI:

dotnet add package MsgKit

步骤2:结合你的代码完成转换

拿到messageToBeSavedAsMSG后,把Graph返回的邮件属性映射到MsgKit的对象里,再保存到本地:

using MsgKit;
using MsgKit.Enums;
using System.IO;

// 你已经获取到的Graph邮件对象
var graphMsg = messageToBeSavedAsMSG;

// 初始化MsgKit的Message实例
using var msgFile = new Message(
    sender: new Sender(graphMsg.Sender.EmailAddress.Name, graphMsg.Sender.EmailAddress.Address),
    recipientTo: new RecipientCollection(),
    subject: graphMsg.Subject
);

// 添加收件人(To/Cc/Bcc)
foreach (var to in graphMsg.ToRecipients)
{
    msgFile.Recipients.AddTo(to.EmailAddress.Name, to.EmailAddress.Address);
}
foreach (var cc in graphMsg.CcRecipients ?? new List<Recipient>())
{
    msgFile.Recipients.AddCc(cc.EmailAddress.Name, cc.EmailAddress.Address);
}
foreach (var bcc in graphMsg.BccRecipients ?? new List<Recipient>())
{
    msgFile.Recipients.AddBcc(bcc.EmailAddress.Name, bcc.EmailAddress.Address);
}

// 设置邮件正文(区分HTML/纯文本格式)
if (graphMsg.Body.ContentType == BodyType.Html)
{
    msgFile.BodyHtml = graphMsg.Body.Content;
}
else
{
    msgFile.BodyText = graphMsg.Body.Content;
}

// 处理附件(需要单独调用Graph获取附件二进制内容)
foreach (var attachment in graphMsg.Attachments ?? new List<Attachment>())
{
    if (attachment is FileAttachment fileAttachment)
    {
        var attachmentContent = graphClient.Users(properties.getUser())
            .Messages(graphMsg.Id)
            .Attachments(attachment.Id)
            .Content()
            .Request()
            .GetAsync()
            .Result;
        
        msgFile.Attachments.Add(fileAttachment.Name, Convert.FromBase64String(attachmentContent));
    }
}

// 保存到本地指定路径
var savePath = @"C:\Your\Local\Path\email.msg";
msgFile.Save(savePath);

小提醒:

  • 发送邮件后立刻取列表第一条可能有延迟,建议加个短暂等待,或者通过发送邮件的返回信息定位目标邮件,避免拿错。
  • 默认获取Message时不会包含附件的二进制数据,所以要单独调用接口拉取。

方案二:通过Outlook COM对象生成(仅Windows环境)

如果你的程序跑在Windows上且装了Outlook客户端,可以直接调用Outlook的COM接口来生成.msg:

步骤1:添加Outlook引用

在项目里添加对Microsoft Outlook xx.x Object Library的引用(xx.x对应你的Outlook版本)。

步骤2:编写转换代码

using Microsoft.Office.Interop.Outlook;

// 初始化Outlook应用
var outlookApp = new Application();
var mailItem = outlookApp.CreateItem(OlItemType.olMailItem);

// 映射Graph邮件属性
mailItem.Subject = messageToBeSavedAsMSG.Subject;
mailItem.SenderName = messageToBeSavedAsMSG.Sender.EmailAddress.Name;
mailItem.SenderEmailAddress = messageToBeSavedAsMSG.Sender.EmailAddress.Address;

// 添加收件人
foreach (var to in messageToBeSavedAsMSG.ToRecipients)
{
    mailItem.Recipients.Add($"{to.EmailAddress.Name} <{to.EmailAddress.Address}>");
}
mailItem.Recipients.ResolveAll();

// 设置正文
if (messageToBeSavedAsMSG.Body.ContentType == BodyType.Html)
{
    mailItem.HTMLBody = messageToBeSavedAsMSG.Body.Content;
}
else
{
    mailItem.Body = messageToBeSavedAsMSG.Body.Content;
}

// 保存为.msg文件
var savePath = @"C:\Your\Local\Path\email.msg";
mailItem.SaveAs(savePath, OlSaveAsType.olMSG);

// 释放COM对象,避免内存泄漏
System.Runtime.InteropServices.Marshal.ReleaseComObject(mailItem);
System.Runtime.InteropServices.Marshal.ReleaseComObject(outlookApp);

小提醒:

  • 这个方法依赖Outlook客户端,服务器端无桌面环境的话不适用。
  • 一定要记得释放COM对象,不然容易内存泄漏。

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

火山引擎 最新活动