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

如何在C# Web Form中用委托权限通过Microsoft Graph API读取邮件附件

问题诊断与解决方案

你的代码核心问题是使用了应用权限(ClientSecretCredential),但需求要求用委托权限,两者权限模型不匹配,导致请求未返回预期结果(甚至可能因权限不足静默失败)。以下是具体修复步骤:

1. 替换认证方式为委托权限类型

委托权限需要模拟用户身份访问,不能用专属应用权限的ClientSecretCredential。根据应用类型选择合适的委托认证方式:

  • 控制台/桌面应用:推荐DeviceCodeCredential或InteractiveBrowserCredential
  • Web应用:使用AuthorizationCodeCredential

以控制台应用常用的DeviceCodeCredential为例:

var scopes = new[] { "Mail.Read" }; // 委托权限只需指定具体权限,无需.default
var tenantId = "tenant_name.onmicrosoft.com";
var clientId = "azure_ad_appid";

// 委托权限认证方式
var deviceCodeCredential = new DeviceCodeCredential(
    (info, cancellation) => {
        Console.WriteLine(info.Message); // 输出设备码登录提示
        return Task.CompletedTask;
    }, tenantId, clientId);

var graphClient = new GraphServiceClient(deviceCodeCredential, scopes);

2. 配置正确的委托权限

在Azure AD应用注册中操作:

  • 进入API权限 -> 添加权限 -> 选择Microsoft Graph
  • 选择委托权限,搜索并添加Mail.Read权限;若需访问其他用户邮箱,添加Mail.Read.Shared(需管理员同意)
  • 点击授予管理员同意(租户范围生效)或让用户自行完成授权

3. 修正查询逻辑并处理附件入库

原代码仅获取邮件集合,未遍历处理附件。以下是包含附件读取及SQL插入的完整示例:

// 获取收件箱带附件的邮件
var inboxMessages = await graphClient
    .Me // 委托权限下用Me指代当前登录用户;访问其他用户需权限支持,替换为Users["tinywang@xx.onmicrosoft.com"]
    .MailFolders["inbox"]
    .Messages
    .Request()
    .Expand("attachments")
    .Top(20)
    .GetAsync();

// 遍历邮件与附件
foreach (var message in inboxMessages)
{
    if (message.Attachments != null && message.Attachments.Any())
    {
        foreach (var attachment in message.Attachments)
        {
            // 仅处理文件类型附件(过滤内嵌图片等)
            if (attachment is FileAttachment fileAttachment)
            {
                var attachmentContent = fileAttachment.ContentBytes;
                
                // 插入SQL数据库(根据你的表结构调整)
                using (var conn = new SqlConnection("你的SQL连接字符串"))
                {
                    await conn.OpenAsync();
                    var sql = @"INSERT INTO EmailAttachments 
                                (MessageId, AttachmentName, Content, CreatedDateTime) 
                                VALUES (@MessageId, @Name, @Content, @CreatedDate)";
                    using (var cmd = new SqlCommand(sql, conn))
                    {
                        cmd.Parameters.AddWithValue("@MessageId", message.Id);
                        cmd.Parameters.AddWithValue("@Name", fileAttachment.Name);
                        cmd.Parameters.AddWithValue("@Content", attachmentContent);
                        cmd.Parameters.AddWithValue("@CreatedDate", message.CreatedDateTime);
                        await cmd.ExecuteNonQueryAsync();
                    }
                }
            }
        }
    }
}

4. 关键注意事项

  • 若邮件数量超过Top(20),需处理分页:通过inboxMessages.NextPageRequest循环获取下一页数据
  • 访问其他用户邮箱时,需确保应用已获得Mail.Read.Shared权限,且目标用户已授权
  • 若使用InteractiveBrowserCredential,需在Azure AD应用中配置正确的重定向URI

内容的提问来源于stack exchange,提问作者Shiv Shankar Maiti

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 06:20:28