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

如何用Microsoft Graph API的C#代码获取Outlook全部邮件

获取Outlook所有文件夹下全部邮件的Microsoft Graph API C#实现方案

核心问题分析

你之前的代码仅针对单个邮件文件夹(默认是收件箱)做了分页获取,但Outlook的邮件分布在多个文件夹中(收件箱、已发送、草稿、自定义文件夹等)。要获取全部邮件,必须先遍历所有邮件文件夹,再逐个文件夹分页拉取邮件。

完整实现方案

步骤1:递归获取所有邮件文件夹

首先需要获取用户所有的邮件文件夹,包括嵌套的子文件夹,用递归方式遍历所有层级:

private async Task<List<MailFolder>> GetAllMailFoldersAsync()
{
    var allFolders = new List<MailFolder>();
    var rootFolders = await _graphServiceClient.Me.MailFolders.Request().GetAsync();
    
    // 遍历根文件夹,递归获取子文件夹
    foreach (var folder in rootFolders)
    {
        allFolders.Add(folder);
        await GetChildFoldersAsync(folder.Id, allFolders);
    }
    
    return allFolders;
}

private async Task GetChildFoldersAsync(string parentFolderId, List<MailFolder> allFolders)
{
    var childFolders = await _graphServiceClient.Me.MailFolders[parentFolderId].ChildFolders.Request().GetAsync();
    foreach (var folder in childFolders)
    {
        allFolders.Add(folder);
        // 递归获取子文件夹的子文件夹
        await GetChildFoldersAsync(folder.Id, allFolders);
    }
}

步骤2:遍历所有文件夹,分页获取邮件

对每个文件夹,使用分页逻辑拉取全部邮件,并合并所有结果:

public async Task<List<Message>> GetAllMessagesFromAllFoldersAsync()
{
    var allMessages = new List<Message>();
    var allFolders = await GetAllMailFoldersAsync();
    
    foreach (var folder in allFolders)
    {
        var folderMessages = await GetAllMessagesFromSingleFolderAsync(folder.Id);
        allMessages.AddRange(folderMessages);
    }
    
    return allMessages;
}

private async Task<List<Message>> GetAllMessagesFromSingleFolderAsync(string folderId)
{
    var messages = new List<Message>();
    var pagedMessages = await _graphServiceClient.Me.MailFolders[folderId].Messages.Request()
        .Select(msg => new 
        {
            msg.Subject,
            msg.BodyPreview,
            msg.ReceivedDateTime,
            msg.FolderId // 可选:记录邮件所属文件夹ID,方便后续区分
        })
        .Top(1000) // 每次拉取Graph API允许的最大数量
        .OrderBy("receivedDateTime desc")
        .GetAsync();
    
    messages.AddRange(pagedMessages.CurrentPage);
    
    // 处理分页,直到没有下一页
    while (pagedMessages.NextPageRequest != null)
    {
        pagedMessages = await pagedMessages.NextPageRequest.GetAsync();
        messages.AddRange(pagedMessages.CurrentPage);
    }
    
    return messages;
}

关键注意事项

  • 权限配置:确保你的应用已申请Mail.Read权限(根据认证方式选择Delegated或Application权限)
  • 性能优化:如果邮件数量极大,可考虑并行拉取多个文件夹的邮件,但要注意Graph API的请求速率限制
  • 错误处理:实际使用中需添加异常捕获逻辑,处理文件夹不存在、请求超时、权限不足等情况
  • 字段精简:通过Select方法只获取需要的字段,减少数据传输量,提升请求效率

对原有代码的修正说明

你之前的代码存在两个核心问题:

  1. 仅请求了Me.Messages或指定用户的Messages接口,这只会返回默认收件箱的邮件,不会覆盖其他文件夹
  2. 缺少遍历所有邮件文件夹的逻辑

通过先递归获取所有文件夹,再逐个拉取每个文件夹的邮件,即可实现获取Outlook全部邮件的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 05:20:29