使用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
相关产品推荐
相关产品推荐

