Microsoft.Graph SDK 连接到用户的 OneDrive 但项目 returns NULL
Microsoft.Graph SDK connects to user's OneDrive but Items returns NULL
我正在使用 Microsoft.Graph SDK 在 C# 中编写一个实用程序来连接和读取用户的 OneDrive。我创建了应用程序注册,授予应用程序 Files.Read.All 权限,并给予管理员同意 per the documentation.
我能够连接到 OneDrive 的 Graph 和元数据:
List<string> scopes = new List<string>();
scopes.Add("https://graph.microsoft.com/.default");
var authenticationProvider = new MsalAuthenticationProvider(cca, scopes.ToArray());
GraphServiceClient graphClient = new GraphServiceClient(authenticationProvider);
var drive = await graphClient.Users[userId].Drive
.Request()
.GetAsync();
它似乎正确连接到 OneDrive,正如 return 正确数据的属性所证明的那样,例如 Quota、Owner,等等
问题是 Items 对象为空,因此我无法读取任何驱动器项目:
我尝试使用 returned 驱动器 ID 直接访问驱动器,但收到相同的结果:
var driveById = await graphClient.Drives[drive.Id]
.Request()
.GetAsync();
我找到的几个示例并未表明任何其他请求选项或缺少权限。那么如何访问 OneDrive 项目?
这个问题的解决方案在评论中给出了,所以为了完整起见,我把它写在这里。
原始代码:
var rootDrive = await GraphClient.Users[UserId].Drive.Request().GetAsync();
此 returns 用户 OneDrive 的元数据,但未捕获 Children。但是,我们稍后会需要此信息,因此最终解决方案同时使用此参考和更新后的代码。
更新代码:
为此,您需要引用驱动器的根目录及其 Children:
var driveItems = await GraphClient.Users[UserId].Drive
.Root
.Children
.Request()
.GetAsync();
这样做 returns IDriveItemChildrenCollectionPage:
处理 CHILDREN:
对于小样本,标准的 foreach 可以正常工作,但对于较大的集合,您需要实施 PageIterator(我还没有这样做)。要获取此 driveItem 的 children,您将需要根元素的驱动器 ID 以及当前的 driveItem.Id:
var children = await GraphClient.Drives[rootDriveId].Items[item.Id].Children.Request().GetAsync()
总的来说,它看起来像这样:
public async Task ListOneDrive()
{
var rootDrive = await GraphClient.Users[UserId].Drive.Request().GetAsync();
var driveItems = await GraphClient.Users[UserId].Drive
.Root
.Children
.Request()
.GetAsync();
foreach (var item in driveItems)
{
await ListDriveItem(rootDrive.Id, item);
}
}
public async Task ListDriveItem(string rootDriveId, DriveItem item, int indentLevel = 1)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < indentLevel; i++)
{
sb.Append($" ");
}
if (item.Folder != null)
{
Console.WriteLine($"{sb.ToString()}> {item.Name}/");
var children = await GraphClient.Drives[rootDriveId].Items[item.Id].Children.Request().GetAsync();
foreach (var child in children)
{
await (ListDriveItem(rootDriveId, child, indentLevel + 1));
}
}
else if (item.File != null)
{
Console.WriteLine($"{sb.ToString()} {item.Name}");
}
}
此示例来自使用递归调用向下钻取所有文件夹的控制台应用程序。如上所述,这两种方法都应该有一个 PageIterator。
我正在使用 Microsoft.Graph SDK 在 C# 中编写一个实用程序来连接和读取用户的 OneDrive。我创建了应用程序注册,授予应用程序 Files.Read.All 权限,并给予管理员同意 per the documentation.
我能够连接到 OneDrive 的 Graph 和元数据:
List<string> scopes = new List<string>();
scopes.Add("https://graph.microsoft.com/.default");
var authenticationProvider = new MsalAuthenticationProvider(cca, scopes.ToArray());
GraphServiceClient graphClient = new GraphServiceClient(authenticationProvider);
var drive = await graphClient.Users[userId].Drive
.Request()
.GetAsync();
它似乎正确连接到 OneDrive,正如 return 正确数据的属性所证明的那样,例如 Quota、Owner,等等
问题是 Items 对象为空,因此我无法读取任何驱动器项目:
我尝试使用 returned 驱动器 ID 直接访问驱动器,但收到相同的结果:
var driveById = await graphClient.Drives[drive.Id]
.Request()
.GetAsync();
我找到的几个示例并未表明任何其他请求选项或缺少权限。那么如何访问 OneDrive 项目?
这个问题的解决方案在评论中给出了,所以为了完整起见,我把它写在这里。
原始代码:
var rootDrive = await GraphClient.Users[UserId].Drive.Request().GetAsync();
此 returns 用户 OneDrive 的元数据,但未捕获 Children。但是,我们稍后会需要此信息,因此最终解决方案同时使用此参考和更新后的代码。
更新代码:
为此,您需要引用驱动器的根目录及其 Children:
var driveItems = await GraphClient.Users[UserId].Drive
.Root
.Children
.Request()
.GetAsync();
这样做 returns IDriveItemChildrenCollectionPage:
处理 CHILDREN:
对于小样本,标准的 foreach 可以正常工作,但对于较大的集合,您需要实施 PageIterator(我还没有这样做)。要获取此 driveItem 的 children,您将需要根元素的驱动器 ID 以及当前的 driveItem.Id:
var children = await GraphClient.Drives[rootDriveId].Items[item.Id].Children.Request().GetAsync()
总的来说,它看起来像这样:
public async Task ListOneDrive()
{
var rootDrive = await GraphClient.Users[UserId].Drive.Request().GetAsync();
var driveItems = await GraphClient.Users[UserId].Drive
.Root
.Children
.Request()
.GetAsync();
foreach (var item in driveItems)
{
await ListDriveItem(rootDrive.Id, item);
}
}
public async Task ListDriveItem(string rootDriveId, DriveItem item, int indentLevel = 1)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < indentLevel; i++)
{
sb.Append($" ");
}
if (item.Folder != null)
{
Console.WriteLine($"{sb.ToString()}> {item.Name}/");
var children = await GraphClient.Drives[rootDriveId].Items[item.Id].Children.Request().GetAsync();
foreach (var child in children)
{
await (ListDriveItem(rootDriveId, child, indentLevel + 1));
}
}
else if (item.File != null)
{
Console.WriteLine($"{sb.ToString()} {item.Name}");
}
}
此示例来自使用递归调用向下钻取所有文件夹的控制台应用程序。如上所述,这两种方法都应该有一个 PageIterator。