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

C#调用Microsoft Graph无法访问OneDrive/SharePoint站点文档库

问题描述

在Azure AD中注册的Graph API完成认证后,无法访问SharePoint站点文档库及用户OneDrive,使用的是Microsoft Graph SDK 5.6版本。微软文档显示可使用.Me.Drive.Root,但代码中找不到该属性,除直接发送HTTP GET请求外已尝试所有方法,希望避免直接调用HTTP。

以下是可正常运行的代码片段:

using Azure.Core;
using Azure.Identity;
using Microsoft.Graph;
using Microsoft.Graph.Models;
using Microsoft.Graph.Me.SendMail;
using Microsoft.Graph.Drives.Item.List.Items.Item.DriveItem;

namespace GraphApp
{
    class GraphHelper
    {
        //Settings object
        private static Settings? _settings;
        // User auth token credential
        private static DeviceCodeCredential? _deviceCodeCredential;
        // Client configured with user auth
        private static GraphServiceClient? _userClient;

        public static void InitializeGraphForUserAuth(Settings settings, Func<DeviceCodeInfo, CancellationToken, Task> deviceCodePrompt)
        {
            _settings = settings;

            var options = new DeviceCodeCredentialOptions
            {
                ClientId = settings.ClientId,
                TenantId = settings.TenantId,
                DeviceCodeCallback = deviceCodePrompt,
            };

            _deviceCodeCredential = new DeviceCodeCredential(options);
            _userClient = new GraphServiceClient(_deviceCodeCredential, settings.GraphUserScopes);
        }
        
        public static async Task<string> GetUserTokenAsync()
        {
            //Ensure cred isn't null
            _ = _deviceCodeCredential ??
                throw new System.NullReferenceException("Graph has not been initialized for auth");

            //Ensure scopes aren't null
            _ = _settings?.GraphUserScopes ?? throw new System.NullReferenceException("Arugment 'scopes' cannot be null");

            // Request token with given scopes
            var context = new TokenRequestContext(_settings.GraphUserScopes);
            var response = await _deviceCodeCredential.GetTokenAsync(context);
            return response.Token;
        }

        public static Task<User?> GetUserAsync()
        {
            //Ensure client isn't null
            _ = _userClient ??
                throw new System.NullReferenceException("Graph has not been initialzed for user auth");

            return _userClient.Me.GetAsync((config) =>
            {
                //Only request specific properties
                config.QueryParameters.Select = new[] { "displayName", "mail", "userPrincipalName" };
            });
        }
    }
}

完整的GraphHelper代码:

using Azure.Core;
using Azure.Identity;
using Microsoft.Graph;
using Microsoft.Graph.Models;
using Microsoft.Graph.Me.SendMail;
using Microsoft.Graph.Drives.Item.List.Items.Item.DriveItem;

namespace GraphApp
{
    class GraphHelper
    {
        //Settings object
        private static Settings? _settings;
        // User auth token credential
        private static DeviceCodeCredential? _deviceCodeCredential;
        // Client configured with user auth
        private static GraphServiceClient? _userClient;

        public static void InitializeGraphForUserAuth(Settings settings, Func<DeviceCodeInfo, CancellationToken, Task> deviceCodePrompt)
        {
            _settings = settings;

            var options = new DeviceCodeCredentialOptions
            {
                ClientId = settings.ClientId,
                TenantId = settings.TenantId,
                DeviceCodeCallback = deviceCodePrompt,
            };

            _deviceCodeCredential = new DeviceCodeCredential(options);
            _userClient = new GraphServiceClient(_deviceCodeCredential, settings.GraphUserScopes);
        }
        
        public static async Task<string> GetUserTokenAsync()
        {
            //Ensure cred isn't null
            _ = _deviceCodeCredential ??
                throw new System.NullReferenceException("Graph has not been initialized for auth");

            //Ensure scopes aren't null
            _ = _settings?.GraphUserScopes ?? throw new System.NullReferenceException("Arugment 'scopes' cannot be null");

            // Request token with given scopes
            var context = new TokenRequestContext(_settings.GraphUserScopes);
            var response = await _deviceCodeCredential.GetTokenAsync(context);
            return response.Token;
        }

        public static Task<User?> GetUserAsync()
        {
            //Ensure client isn't null
            _ = _userClient ??
                throw new System.NullReferenceException("Graph has not been initialzed for user auth");

            return _userClient.Me.GetAsync((config) =>
            {
                //Only request specific properties
                config.QueryParameters.Select = new[] { "displayName", "mail", "userPrincipalName" };
            });
        }

        public static Task<MessageCollectionResponse?> GetInboxAsync()
        {
            //Ensure client isn't null
            _ = _userClient ??
                throw new System.NullReferenceException("Graph has not been initialized for user auth");

            return _userClient.Me
                //Only messages from Inbox
                .MailFolders["Inbox"]
                .Messages
                .GetAsync((config) =>
                {
                    //Only request specific properties
                    config.QueryParameters.Select = new[] { "from", "isRead", "receivedDateTime", "subject" };
                    // Get only top 25 results
                    config.QueryParameters.Top = 25;
                    //Sort by received time, newest first
                    config.QueryParameters.Orderby = new[] { "receivedDateTime DESC" };
                });
            
        }

        public static async Task SendMailAsync(string subject, string body, string recipient)
        {
            //ensure client isn't null
            _ = _userClient ??
                throw new System.NullReferenceException("Graph has not been initialized for user auth");

            //Create the message
            var message = new Message
            {
                Subject = subject,
                Body = new ItemBody
                {
                    Content = body,
                    ContentType = BodyType.Text
                },
                ToRecipients = new List<Recipient>
                {
                    new Recipient
                    {
                        EmailAddress = new EmailAddress
                        {
                            Address = recipient
                        }
                    }
                }
            };

            //Send the message

            await _userClient.Me
                .SendMail
                .PostAsync(new SendMailPostRequestBody
                {
                    Message = message
                });
        }

        public static async Task GetSiteDetails(string sitename) //doesn't work
        {
            
            //ensure client isn't null
            _ = _userClient ??
                throw new System.NullReferenceException("Graph has not been initialized for user auth");
            
            var result = await _userClient.Sites.GetAsync((requestConfiguration) =>
            {
                requestConfiguration.QueryParameters.Search = $"{sitename}";
            });
        }

        public static async Task GetDrive()
        {
            //ensure client isn't null
            _ = _userClient ??
                throw new System.NullReferenceException("Graph has not been initialized for user auth");

            var childItems = _userClient.Me.Drive.
        }

    }
}
解决方法

1. 安装缺失的NuGet模块

Microsoft Graph SDK 5.x采用模块化设计,仅安装核心Microsoft.Graph包不足以覆盖所有功能。需手动添加对应模块:

  • 安装Microsoft.Graph.Drives以支持OneDrive相关API
  • 安装Microsoft.Graph.Sites以支持SharePoint站点相关API

在NuGet包管理器中执行命令:

Install-Package Microsoft.Graph.Drives
Install-Package Microsoft.Graph.Sites

2. 配置正确的权限范围

确保settings.GraphUserScopes包含访问OneDrive和SharePoint所需的权限,示例配置:

var graphUserScopes = new[] { "User.Read", "Mail.Read", "Files.Read", "Sites.Read.All" };

按需选择权限:

  • OneDrive:Files.Read/Files.ReadWrite/Files.Read.All
  • SharePoint:Sites.Read.All/Sites.ReadWrite.All

3. 修正代码调用逻辑

SDK 5.x中异步方法必须使用await,且API调用需遵循正确链式结构。修正GetDrive和GetSiteDetails方法:

修正OneDrive调用

public static async Task GetDrive()
{
    _ = _userClient ?? throw new System.NullReferenceException("Graph has not been initialized for user auth");

    // 获取当前用户OneDrive根目录
    var driveRoot = await _userClient.Me.Drive.Root.GetAsync();
    // 获取根目录下的子文件/文件夹
    var childItems = await _userClient.Me.Drive.Root.Children.GetAsync();
}

修正SharePoint站点调用

public static async Task GetSiteDetails(string siteUrl)
{
    _ = _userClient ?? throw new System.NullReferenceException("Graph has not been initialized for user auth");

    // 通过站点URL获取站点实例
    var site = await _userClient.Sites.GetByPath(siteUrl, "root").GetAsync();
    // 获取站点默认文档库
    var siteDrive = await _userClient.Sites[site.Id].Drives.GetAsync();
}

4. 添加必要命名空间

确保代码中引用以下命名空间,以获取完整API提示:

using Microsoft.Graph.Me.Drive;
using Microsoft.Graph.Sites;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 23:07:52