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

Microsoft Graph 5.8.0下载20MB以上附件失败求助

解决Microsoft Graph 5.x下载大附件超时(504)问题

针对你遇到的Graph 5.x版本下载20MB以上附件超时的问题,核心原因是通过expand=attachments一次性拉取附件内容会将大文件数据与邮件元数据合并返回,极易触发服务器或客户端超时。以下是有效解决方案:

1. 改用单独的附件内容下载端点

不要通过expand拉取附件内容,而是:

  • 先获取邮件的附件元数据列表(仅包含Id、名称、大小等信息,不包含附件内容)
  • 针对大附件,调用/users/{user-id}/messages/{message-id}/attachments/{attachment-id}/$value端点流式下载内容,该端点专门优化了大文件传输。

2. 调整代码实现

修改你的代码如下:

var httpClient = new HttpClient
{
    Timeout = TimeSpan.FromMinutes(45), // 保持客户端超时设置
};
var clientCredentialAuthProvider = new ClientCredentialAuthProvider(configuration);
var graphClient = new Microsoft.Graph.GraphServiceClient(httpClient, clientCredentialAuthProvider);

// 1. 获取目标邮件(无需expand attachments)
var messages = await graphClient.Users[configuration.SharedMailBox].MailFolders[configuration.InboxFolderId].Messages
    .GetAsync(requestConfig => 
    {
        requestConfig.QueryParameters.Select = configuration.FilterConfiguration.Properties;
        requestConfig.QueryParameters.Filter = configuration?.FilterConfiguration?.Filters ?? string.Empty;
        requestConfig.QueryParameters.Top = configuration?.FilterConfiguration?.MessageCount ?? 1;
        // 移除expand=attachments,避免一次性拉取大附件
    });

var latestMail = messages.Value.FirstOrDefault();
if (latestMail is null) return;

_logger.LogInformation("{DownloadAttachmentFromMailByFileNameAsync}", "Email downloaded successfully.");
_logger.LogInformation("{DownloadAttachmentFromMailByFileNameAsync}", "Initiating attachment download.");

// 2. 获取该邮件的附件元数据列表
var attachments = await graphClient.Users[configuration.SharedMailBox].MailFolders[configuration.InboxFolderId].Messages[latestMail.Id].Attachments
    .GetAsync(requestConfig =>
    {
        // 仅选择需要的元数据,减少响应大小
        requestConfig.QueryParameters.Select = new string[] { "Id", "Name", "Size" };
    });

// 3. 遍历附件,流式下载大附件
foreach (var attachment in attachments.Value.Where(a => a.Size > 20 * 1024 * 1024))
{
    using var cts = new CancellationTokenSource(TimeSpan.FromHours(1));
    // 调用$value端点获取附件流
    var attachmentStream = await graphClient.Users[configuration.SharedMailBox].MailFolders[configuration.InboxFolderId].Messages[latestMail.Id].Attachments[attachment.Id].Content
        .GetAsync(cancellationToken: cts.Token);
    
    // 将流保存到本地或处理
    using var fileStream = new FileStream(Path.Combine("downloads", attachment.Name), FileMode.Create);
    await attachmentStream.CopyToAsync(fileStream, cts.Token);
}

3. 额外优化建议

  • 流式处理:始终使用流操作处理大附件,避免将整个文件加载到内存中,减少内存压力和超时概率。
  • 重试机制:针对504超时错误,使用重试库(如Polly)添加指数退避重试逻辑,应对临时的服务器负载问题。
  • 确认权限:确保应用拥有Mail.Read权限(应用权限或委派权限),且权限范围足够访问目标共享邮箱。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 06:23:14