我目前正在尝试实现几个任务,这些任务涉及从共享的 OneDrive 文件夹中列出、上传和下载文件。该文件夹可以通过已登录用户的 OneDrive(在其根文件夹中可见)访问。至目前为止,使用以下代码,列出文件这一部分工作得非常好:
string remoteDriveId = string.Empty;
private GraphServiceClient graphClient { get; set; }
// Get the root of the owners OneDrive
DriveItem ownerRoot = await this.graphClient.Drive.Root.Request().Expand("thumbnails,children($expand=thumbnails)").GetAsync();
// Select the shared folders general information
DriveItem sharedFolder = ownerRoot.Children.Where(c => c.Name == "sharedFolder").FirstOrDefault();
// Check if it is a remote folder
if(sharedFolder.Remote != null)
{
remoteDriveId = item.RemoteItem.ParentReference.DriveId;
// Get complete Information of the shared folder
sharedFolder = await graphClient.Drives[remoteDriveId].Items[sharedFolder.RemoteItem.Id].Request().Expand("thumbnails,children").GetAsync();
}
显然,我需要从与另一个OneDrive共享的OneDrive中检索共享文件夹信息。 接下来要做的是列出此共享文件夹的内容,这也可以像这样很好地完成:
foreach (DriveItem child in sharedFolder.Children)
{
DriveItem childItem = await graphClient.Drives[remoteDriveId].Items[child.Id].Request().Expand("thumbnails,children").GetAsync();
if(childItem.Folder == null)
{
string path = Path.GetTempPath() + Guid.NewGuid();
// Download child item to path
}
}
我的问题始于"下载子项到路径"这一部分。我想要下载所有非文件夹的内容到一个临时文件中。但问题在于,OneDrive总是用错误消息回应我的请求,说找不到该文件。我到目前为止尝试过的方法有:
using (var stream = await graphClient.Drives[remoteDriveId].Items[childItem.Id].Content.Request().GetAsync())
using (var outputStream = new System.IO.FileStream(path, System.IO.FileMode.Create))
{
await stream.CopyToAsync(outputStream);
}
在另一种变体中,我试图使用childItem ParentReference的ID(但我认为这只会导致我获得共享文件夹的远程OneDrive ID):
using (var stream = await graphClient.Drives[remoteDriveId].Items[childItem.ParentReference.Id].Content.Request().GetAsync())
using (var outputStream = new System.IO.FileStream(path, System.IO.FileMode.Create))
{
await stream.CopyToAsync(outputStream);
}
下载文件后,我想编辑它们并重新上传到共享文件夹中的不同路径。这个路径是由我创建的(已经可以使用),如下所示:
DriveItem folderToCreate = new DriveItem { Name = "folderName", Folder = new Folder() };
await graphClient.Drives[remoteDriveId].Items[sharedFolder.Id].Children.Request().AddAsync(folderToCreate);
上传失败。我已尝试过这样做:using (var stream = new System.IO.FileStream(@"C:\temp\testfile.txt", System.IO.FileMode.Open))
{
await graphClient.Drives[remoteDriveId].Items[sharedFolder.Id].Content.Request().PutAsync<DriveItem>(stream);
}
如果不是共享文件夹,我也可以这样做(这在我使用Drive
而不是Drives
时有效):
using (var stream = new System.IO.FileStream(@"C:\temp\testfile.txt", System.IO.FileMode.Open))
{
string folderPath = sharedFolder.ParentReference == null ? "" : sharedFolder.ParentReference.Path.Remove(0, 12) + "/" + Uri.EscapeUriString(sharedFolder.Name);
var uploadPath = folderPath + "/" + uploadFileName;
await graphClient.Drives[remoteDriveId].Root.ItemWithPath(uploadPath).Content.Request().PutAsync<DriveItem>(stream);
}
我无法让AddAsync
方法(就像在创建文件夹时)起作用,因为我不知道如何从Stream
创建DriveItem
。
如果有人能指点我正确的方向,我将非常感激!谢谢!
@content.downloadUrl
(它可能在AdditionalData
字典中)。你需要创建一个HttpWebRequest
(或类似的)来获取响应流,但这实际上会节省一次往返,因为/content
在内部执行了重定向。 - Brad