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

使用Microsoft Graph获取Office365邮件附件遇空引用错误求助

问题原因及解决方案

问题根源

你遇到的空引用错误,是因为Microsoft Graph API默认获取邮件(Message)资源时,不会自动返回附件(Attachments)数据。即使HasAttachments为true,item.Attachments属性依然是null,直接访问CurrentPage自然会抛出空引用异常。

解决方法

结合你的需求(读取未读邮件、下载附件、标记已读),提供两种可行处理方式:

方法1:获取邮件时预加载附件(高效推荐)

在请求邮件时通过$expand参数内嵌返回附件数据,避免后续单独请求,同时可一次性完成标记已读操作:

// Auth code omitted for brevity...

var graphClient = new GraphServiceClient(clientSecretCredential, scopes);

var messages = await graphClient.Users["ipaqpc@mymail.com"].Messages
        .Request()
        .Filter("isRead eq false")
        .Expand("attachments") // 关键:预加载附件数据
        .Select("id,subject,sender,hasAttachments,isRead") // 按需选择字段,提升请求性能
        .GetAsync();

Console.WriteLine(messages.Count); // Returns "10".

foreach (var item in messages.CurrentPage)
{
    Console.WriteLine($"发件人:{item.Sender.EmailAddress.Address}");
    
    // 标记邮件为已读
    await graphClient.Users["ipaqpc@mymail.com"].Messages[item.Id]
        .Request()
        .UpdateAsync(new Message { IsRead = true });

    if (item.HasAttachments == true)
    {
        Console.WriteLine("包含附件");
        // 此时Attachments已被预加载,可直接遍历
        foreach (var attachment in item.Attachments)
        {
            Console.WriteLine($"附件名称:{attachment.Name}");
            
            // 下载文件类型附件(忽略内嵌附件等其他类型)
            if (attachment is FileAttachment fileAttachment)
            {
                // 将附件内容保存到本地路径
                File.WriteAllBytes($"本地保存路径\\{fileAttachment.Name}", fileAttachment.ContentBytes);
                Console.WriteLine($"已下载附件:{fileAttachment.Name}");
            }
        }
    }
}

方法2:单独请求单封邮件的附件

如果邮件数量多、附件体积大,不想一次性加载所有附件,可在判断HasAttachments为true后,单独请求该邮件的附件资源:

// Auth code omitted for brevity...

var graphClient = new GraphServiceClient(clientSecretCredential, scopes);

var messages = await graphClient.Users["ipaqpc@mymail.com"].Messages
        .Request()
        .Filter("isRead eq false")
        .Select("id,subject,sender,hasAttachments,isRead")
        .GetAsync();

Console.WriteLine(messages.Count); // Returns "10".

foreach (var item in messages.CurrentPage)
{
    Console.WriteLine($"发件人:{item.Sender.EmailAddress.Address}");
    
    // 标记邮件为已读
    await graphClient.Users["ipaqpc@mymail.com"].Messages[item.Id]
        .Request()
        .UpdateAsync(new Message { IsRead = true });

    if (item.HasAttachments == true)
    {
        Console.WriteLine("包含附件");
        // 单独请求当前邮件的附件列表
        var attachments = await graphClient.Users["ipaqpc@mymail.com"].Messages[item.Id].Attachments
            .Request()
            .GetAsync();
        
        foreach (var attachment in attachments.CurrentPage)
        {
            Console.WriteLine($"附件名称:{attachment.Name}");
            
            // 下载文件类型附件
            if (attachment is FileAttachment fileAttachment)
            {
                File.WriteAllBytes($"本地保存路径\\{fileAttachment.Name}", fileAttachment.ContentBytes);
                Console.WriteLine($"已下载附件:{fileAttachment.Name}");
            }
        }
    }
}

额外注意事项

  • 权限验证:确保应用已申请Mail.ReadWrite权限(委托或应用权限),否则无法完成读取邮件、下载附件、标记已读操作。
  • 附件类型处理:邮件附件包含FileAttachment、ItemAttachment等多种类型,需根据业务需求针对性处理,示例仅覆盖常见的文件附件场景。
  • 分页处理:如果未读邮件或附件数量超过默认分页限制(通常为100条),需调用messages.NextPageRequest.GetAsync()获取后续数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 11:49:00