【问题标题】:Access shared file/folder by relative path通过相对路径访问共享文件/文件夹
【发布时间】:2020-01-28 07:46:44
【问题描述】:

我正在构建一个客户端来访问用户 OneDrive 中的文件,使用 MSGraph SDK(适用于 .net,在 Android 上运行)。

我已经计算了 sharedId 以便我可以访问

client.Shares[shareId].Root.Children
                .Request()
                .GetAsync()

其中 shareId 是u!aHR0cHM6Ly8xZHJ2Lm1zL2YvcyFBdHVBTV9OYWN3VmFoaUZwdU1HU19CaVFDd1d1 形式的字符串(按the API docs 中所述计算

现在我想列出一个子文件夹的内容,所以我调用

client.Shares[shareId].Root.ItemWithPath("subfolder").Children
                .Request()
                .GetAsync()

其中“子文件夹”是现有的子文件夹名称。

但是,我在调用 ItemWithPath() 时检索到 Resource not found for the segment 'root'

据我了解,这种对与另一个项目相关的文件的访问应该根据the docs on path-based-addressing 工作(它适用于用户驱动器内的文件/文件夹,但不适用于共享内的项目)。

这是一个限制吗?我是否需要为要访问的每个共享文件存储 driveItemId?或者是否有更简单的解决方案,以便我可以像处理用户驱动器中的文件一样处理共享文件?

【问题讨论】:

    标签: c# microsoft-graph-api onedrive


    【解决方案1】:

    确实,似乎不支持这种基于路径的寻址。但可以考虑以下选项

    选项 1

    将单个请求拆分为以下子请求:

    • 通过shareId获取parent文件夹:GET /shares/{shareId}/root
    • 通过提供父文件夹的DriveItem.Id 以及来自先前请求的Drive.Id 来获取子文件夹项目:GET /drives/{drive-id}/items/{parent-item-id}:/{sub-folder-name}:/children

    这是一个例子:

    var parentDriveItem = await graphClient.Shares[shareId].Root
         .Request()
         .GetAsync();
    
    
    var items = await graphClient.Drives[parentDriveItem.ParentReference.DriveId].Items[parentDriveItem.Id]
        .ItemWithPath(subFolderName)
         .Children
         .Request()
         .GetAsync();
    
         //print results
         foreach (var item in items)
         {
              Console.WriteLine(item.Name);
         }
    

    选项 2

    这个想法是通过为子文件夹生成共享令牌来解决驱动器项目
    Given the implementation 用于编码共享 URL,将其解码回的方法 (UrlDecode) 是还介绍了:

    public static class SharingUtility
    {
        public static string UrlEncode(string value)
        {
            var base64Value = System.Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(value));
            return "u!" + base64Value.TrimEnd('=').Replace('/','_').Replace('+','-');
        }
    
        public static string UrlDecode(string encodedValue)
        {
            var safeEncodedValue = encodedValue.Replace('_','/').Replace('-','+').Substring(2) + "==";
            var bytes = System.Convert.FromBase64String(safeEncodedValue);
            var value = System.Text.Encoding.UTF8.GetString(bytes);
            return value;
        }
    }
    

    现在可以根据父文件夹的共享令牌生成共享令牌:

    var parentShareId = SharingUtility.UrlEncode(sharingUrl); //refers to parent folder
    //generate share id for sub folder
    var shareId = SharingUtility.UrlEncode(SharingUtility.UrlDecode(parentShareId) + "/" + subFolderName);  
    //address shared drive item 
    var items = await graphClient.Shares[shareId].Root.Children
                .Request()
                .GetAsync();
    
    foreach (var item in items)
    {
        Console.WriteLine(item.Name);
    }
    

    【讨论】:

    • 不幸的是,选项 2 似乎仅适用于 OneDrive for Business 帐户。在我的个人 OneDrive 帐户上,WebUrl 不是从本地路径构建的。
    • @Philipp,确实,OneDrive Personal 的选项 2 似乎不可靠
    猜你喜欢
    • 2016-07-31
    • 2011-03-06
    • 1970-01-01
    • 1970-01-01
    • 2019-06-30
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多