通过Teams应用使用MS Graph SDK获取组SharePoint站点并上传文件时,站点Drive始终为空的问题
解决MS Graph SDK中site.Drive为null的问题
我之前也碰到过一模一样的情况!问题出在Graph API默认不会自动返回关联的导航属性,你当前的请求只获取了Site的基础信息,没有拉取Drive资源,所以SDK里的site.Drive自然是null。而你在Postman里调用的groups/{{id}}/site/root接口,应该是直接获取了包含Drive关联信息的站点数据,所以能拿到正常结果。
解决方案1:获取Site时显式展开Drive属性
修改你获取Site的代码,添加.Expand()方法来指定要加载Drive导航属性:
var siteName = "testSite"; // 添加.Expand(x => x.Drive)拉取Drive关联资源 var site = (await graphService.Groups[groupId].Sites.Request() .Expand(x => x.Drive) .GetAsync()) .FirstOrDefault(x => x.DisplayName == siteName); if (site?.Drive != null) { using var wc = new WebClient(); using var stream = new MemoryStream(wc.DownloadData(attachment.DownloadUrl)); var uploadedFile = await site.Drive.Root .ItemWithPath($"Test/123/file.jpg").Content.Request().PutAsync<DriveItem>(stream); }
解决方案2:直接获取组的根站点(更高效)
通常每个Office 365组对应唯一的SharePoint根站点,你可以直接通过Groups[groupId].Site.Root获取,无需枚举所有站点再过滤,同时展开Drive:
// 直接获取组的根站点并展开Drive var site = await graphService.Groups[groupId].Site.Root.Request() .Expand(x => x.Drive) .GetAsync(); using var wc = new WebClient(); using var stream = new MemoryStream(wc.DownloadData(attachment.DownloadUrl)); var uploadedFile = await site.Drive.Root .ItemWithPath($"Test/123/file.jpg").Content.Request().PutAsync<DriveItem>(stream);
备选方案:单独请求Site的Drive
如果因为某些原因无法在获取Site时展开Drive,也可以拿到Site ID后单独请求Drive资源:
var siteName = "testSite"; var site = (await graphService.Groups[groupId].Sites.Request().GetAsync()) .FirstOrDefault(x => x.DisplayName == siteName); if (site != null) { // 单独获取该Site的Drive资源 var drive = await graphService.Sites[site.Id].Drive.Request().GetAsync(); using var wc = new WebClient(); using var stream = new MemoryStream(wc.DownloadData(attachment.DownloadUrl)); var uploadedFile = await drive.Root .ItemWithPath($"Test/123/file.jpg").Content.Request().PutAsync<DriveItem>(stream); }
核心逻辑就是Graph的延迟加载机制:默认只返回资源的核心属性,关联的导航属性必须通过$expand参数显式请求,SDK里的.Expand()方法就是帮你自动添加这个参数的。你的权限配置完全没问题,只要修正请求逻辑就能解决问题。
内容的提问来源于stack exchange,提问作者Corv1nus




