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

使用C#结合Microsoft Graph API读取带附件邮件并转.eml等问题

使用C# + Microsoft Graph API 处理邮件的完整解决方案

1. 版本兼容性确认

Microsoft Graph SDK 5.49.0与.NET 5.0完全兼容。SDK 5.x系列官方支持.NET 5.0及以上版本(包括.NET 6.0、.NET 7.0等),无需担心版本适配问题。

2. 解决HasAttachments为true但Attachments为空的问题

默认查询邮件时,Graph API不会自动加载附件数据,因此即使HasAttachments为true,message.Attachments也会为空。解决方式有两种:

  • 方式一:查询邮件时主动展开附件
    在调用GetAsync()前添加.Expand("attachments"),一次性获取邮件及附件数据。
  • 方式二:单独获取单封邮件的附件
    针对单封邮件,调用附件接口单独拉取:_graphServiceClient.Users[userId].Messages[message.Id].Attachments.GetAsync()

3. 完整功能示例代码

以下代码包含读取带附件邮件、保存为.eml文件、移动邮件至指定文件夹的完整实现:

using Azure.Identity;
using Microsoft.Graph;
using Microsoft.Graph.Models;
using System.IO;

// 初始化GraphServiceClient(以ClientSecret认证为例,根据实际场景替换认证方式)
var tenantId = "你的租户ID";
var clientId = "你的客户端ID";
var clientSecret = "你的客户端密钥";
var userId = "目标用户邮箱或ID";
var targetFolderId = "目标文件夹ID(可通过Graph API获取文件夹列表得到)";

var credential = new ClientSecretCredential(tenantId, clientId, clientSecret);
var _graphServiceClient = new GraphServiceClient(credential);

try
{
    // 读取收件箱邮件,同时展开附件数据
    var messages = await _graphServiceClient.Users[userId].MailFolders["inbox"].Messages
        .GetAsync(requestConfiguration =>
        {
            requestConfiguration.QueryParameters.Expand = new string[] { "attachments" };
            // 可按需添加筛选条件,比如只获取带附件的邮件
            requestConfiguration.QueryParameters.Filter = "HasAttachments eq true";
        });

    foreach (var message in messages.Value)
    {
        Console.WriteLine($"处理邮件:{message.Subject}");

        // 1. 将邮件保存为.eml文件
        var mimeContent = await _graphServiceClient.Users[userId].Messages[message.Id].Content.GetAsync();
        using var fileStream = new FileStream($"{message.Subject}.eml", FileMode.Create);
        await mimeContent.CopyToAsync(fileStream);
        Console.WriteLine($"已保存为EML文件:{message.Subject}.eml");

        // 2. 打印附件信息(如果需要处理附件内容,可在此处扩展)
        if (message.Attachments != null && message.Attachments.Any())
        {
            Console.WriteLine("附件列表:");
            foreach (var attachment in message.Attachments)
            {
                if (attachment is FileAttachment fileAttachment)
                {
                    Console.WriteLine($"- {fileAttachment.Name}(大小:{fileAttachment.Size}字节)");
                    // 如需保存附件,可使用fileAttachment.ContentBytes转换为文件
                }
            }
        }

        // 3. 将邮件从收件箱移动至目标文件夹
        await _graphServiceClient.Users[userId].Messages[message.Id].Move.PostAsync(
            new MovePostRequestBody { DestinationId = targetFolderId });
        Console.WriteLine($"已移动邮件至目标文件夹");
    }
}
catch (Exception ex)
{
    Console.WriteLine($"处理出错:{ex.Message}");
}

关键代码说明

  • 附件加载:通过Expand("attachments")在查询邮件时关联加载附件,避免二次请求;若邮件数量大,也可单独获取单封邮件的附件以减少单次请求数据量。
  • EML转换:调用Messages[message.Id].Content.GetAsync()直接获取邮件的MIME格式流,写入文件即为标准.eml文件,无需额外转换逻辑。
  • 邮件移动:使用Move.PostAsync()方法,传入目标文件夹ID即可完成移动,目标文件夹ID可通过_graphServiceClient.Users[userId].MailFolders.GetAsync()获取所有邮箱文件夹的ID。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 23:37:44