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

使用Graph SDK 5.5(C#)获取Office365邮件附件遇阻求助

解决Graph SDK 5.5获取Office365邮件附件的问题

核心问题分析

你代码里获取附件的行报错,根源是异步方法未加await:GetAsync()返回的是Task<AttachmentCollectionResponse>类型的任务对象,不是直接的附件集合,直接foreach会触发编译或运行时错误。另外,批量获取所有附件无需手动找attachment id——只有单独获取某一个特定附件时才需要id,直接调用Attachments.GetAsync()就能拿到当前邮件的所有附件。

修正后的完整代码

var credentials = new ClientSecretCredential(directoryTenantID, applicationClientID, secretID);
var graphServiceClient = new GraphServiceClient(credentials);

try
{
    // 方式1:先拉取邮件,再逐个获取附件(适合附件体积大、数量多的场景)
    var messageCollectionResponse = await graphServiceClient
        .Users["***********"]
        .MailFolders["Inbox"]
        .Messages
        .GetAsync(config => 
        {
            config.QueryParameters.Top = 50;
            // 可选:只获取必要字段,减少数据传输
            config.QueryParameters.Select = new[] { "Id", "Subject", "HasAttachments" };
        });

    var messages = messageCollectionResponse.Value;

    foreach (var message in messages)
    {
        // 先判断邮件是否有附件,避免无效API请求
        if (message.HasAttachments == true)
        {
            // 必须加await,等待异步任务完成后获取附件集合
            var attachmentResponse = await graphServiceClient
                .Users["ITOC_Resolve@bcx.co.za"]
                .Messages[message.Id]
                .Attachments
                .GetAsync();

            var attachments = attachmentResponse.Value;

            foreach (var attachment in attachments)
            {
                // 仅处理文件类型附件(Attachment是基类,还包含ItemAttachment等类型)
                if (attachment is FileAttachment fileAttachment)
                {
                    var saveDir = @"C:\Attachments";
                    var savePath = Path.Combine(saveDir, fileAttachment.Name);
                    // 确保保存目录存在
                    Directory.CreateDirectory(saveDir);
                    // 写入附件内容到本地文件
                    File.WriteAllBytes(savePath, fileAttachment.ContentBytes);
                }
            }
        }
    }

    // ------------------------------
    // 方式2:一次性拉取邮件+附件(减少API调用次数,适合附件体积小的场景)
    // var messageCollectionWithAttachments = await graphServiceClient
    //     .Users["***********"]
    //     .MailFolders["Inbox"]
    //     .Messages
    //     .GetAsync(config => 
    //     {
    //         config.QueryParameters.Top = 50;
    //         // 通过Expand参数一次性获取邮件关联的附件
    //         config.QueryParameters.Expand = new[] { "attachments" };
    //     });

    // foreach (var message in messageCollectionWithAttachments.Value)
    // {
    //     if (message.Attachments != null)
    //     {
    //         foreach (var attachment in message.Attachments)
    //         {
    //             if (attachment is FileAttachment fileAttachment)
    //             {
    //                 var saveDir = @"C:\Attachments";
    //                 var savePath = Path.Combine(saveDir, fileAttachment.Name);
    //                 Directory.CreateDirectory(saveDir);
    //                 File.WriteAllBytes(savePath, fileAttachment.ContentBytes);
    //             }
    //         }
    //     }
    // }
}
catch (Exception ex)
{
    // 按需处理异常
    Console.WriteLine($"错误信息:{ex.Message}");
}

关于Attachment ID的说明

只有当你需要单独获取某一个特定附件时,才需要用到attachment id,示例如下:

// 从附件集合中拿到目标附件的Id
var targetAttachmentId = attachments.First().Id;

// 根据Id获取单个附件详情
var singleAttachment = await graphServiceClient
    .Users["{user_id}"]
    .Messages["{message_id}"]
    .Attachments[targetAttachmentId]
    .GetAsync();

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

相关产品推荐
方舟 Agent Plan

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

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