Rom*_*mbé 9 c# onedrive microsoft-graph
我目前正在尝试执行一些任务,这些任务涉及从共享的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();
}
Run Code Online (Sandbox Code Playgroud)
因此,显然我需要从与另一个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
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题始于“将子项下载到路径”部分。我要在那里下载所有内容,而不是将其下载到临时文件的文件夹。问题在于,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);
}
Run Code Online (Sandbox Code Playgroud)
在另一个变体中,我尝试使用childItem ParentReference的ID(但是我认为这只会导致我找到sharedFolder的远程OneDrives 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);
}
Run Code Online (Sandbox Code Playgroud)
下载文件后,我要编辑它们并将它们重新上传到共享文件夹中的其他路径。该路径是由我创建的(已经可以使用),如下所示:
DriveItem folderToCreate = new DriveItem { Name = "folderName", Folder = new Folder() };
await graphClient.Drives[remoteDriveId].Items[sharedFolder.Id].Children.Request().AddAsync(folderToCreate);
Run Code Online (Sandbox Code Playgroud)
然后上传失败。我已经这样尝试过了:
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);
}
Run Code Online (Sandbox Code Playgroud)
并且也这样(如果它不是共享文件夹,则可以使用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);
}
Run Code Online (Sandbox Code Playgroud)
我无法使用该AddAsync方法(例如在创建文件夹中),因为我不知道如何从中创建DriveItem一个Stream。
如果有人能指出正确的方向,我将不胜感激!谢谢!
请求:
graphClient.Drives[remoteDriveId].Items[childItem.ParentReference.Id].Content.Request().GetAsync()
Run Code Online (Sandbox Code Playgroud)
对应于下载 DriveItem 端点的内容,并且仅childItem.ParentReference.Id在引用File资源时才有效,在另一种情况下,它会失败并出现预期的异常:
Microsoft.Graph.ServiceException:代码:itemNotFound 消息:您无法获取文件夹的内容
因此,要从文件夹下载内容,解决方案是:
GET /drives/{drive-id}/items/{folderItem-id}/children driveItem对应于一个File方面,则显式下载其内容:GET /drives/{drive-id}/items/{fileItem-id}/content 例子
var sharedItem = await graphClient.Drives[driveId].Items[folderItemId].Request().Expand(i => i.Children).GetAsync();
foreach (var item in sharedItem.Children)
{
if (item.File != null)
{
var fileContent = await graphClient.Drives[item.ParentReference.DriveId].Items[item.Id].Content.Request()
.GetAsync();
using (var fileStream = new FileStream(item.Name, FileMode.Create, System.IO.FileAccess.Write))
fileContent.CopyTo(fileStream);
}
}
Run Code Online (Sandbox Code Playgroud)
实施例2
该示例演示如何从源文件夹下载文件并将其上传到目标文件夹:
var sourceDriveId = "--source drive id goes here--";
var sourceItemFolderId = "--source folder id goes here--";
var targetDriveId = "--target drive id goes here--";
var targetItemFolderId = "--target folder id goes here--";
var sourceFolder = await graphClient.Drives[sourceDriveId].Items[sourceItemFolderId].Request().Expand(i => i.Children).GetAsync();
foreach (var item in sourceFolder.Children)
{
if (item.File != null)
{
//1. download a file as a stream
var fileContent = await graphClient.Drives[item.ParentReference.DriveId].Items[item.Id].Content.Request()
.GetAsync();
//save it into file
//using (var fileStream = new FileStream(item.Name, FileMode.Create, System.IO.FileAccess.Write))
// fileContent.CopyTo(fileStream);
//2.Upload file into target folder
await graphClient.Drives[targetDriveId]
.Items[targetItemFolderId]
.ItemWithPath(item.Name)
.Content
.Request()
.PutAsync<DriveItem>(fileContent);
}
}
Run Code Online (Sandbox Code Playgroud)
我认为您实际上追求的是操作,而不是下载/上传文件DriveItem copy内容move。假设需要将一些文件从一个 ( ) 文件夹复制source到另一个 ( target) 文件夹中,那么以下示例演示了如何完成它:
var sourceDriveId = "--source drive id goes here--";
var sourceItemFolderId = "--source folder id goes here--";
var targetDriveId = "--target drive id goes here--";
var targetItemFolderId = "--target folder id goes here--";
var sourceFolder = await graphClient.Drives[sourceDriveId].Items[sourceItemFolderId].Request().Expand(i => i.Children).GetAsync();
foreach (var item in sourceFolder.Children)
{
if (item.File != null)
{
var parentReference = new ItemReference
{
DriveId = targetDriveId,
Id = targetItemFolderId
};
await graphClient.Drives[sourceDriveId].Items[item.Id]
.Copy(item.Name, parentReference)
.Request()
.PostAsync();
}
}
}
Run Code Online (Sandbox Code Playgroud)