Доступ к общему файлу/папке по относительному пути

Я создаю клиент для доступа к файлам в OneDrive пользователя, используя SDK MSGraph (для .net, работающий на Android).

Я рассчитал общий идентификатор, поэтому я могу получить доступ

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

где shareId — это строка в форме u!aHR0cHM6Ly8xZHJ2Lm1zL2YvcyFBdHVBTV9OYWN3VmFoaUZwdU1HU19CaVFDd1d1 (рассчитывается, как описано в документы по API

Теперь я хотел бы вывести содержимое подпапки, поэтому я вызываю

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

где «подпапка» — это имя существующей подпапки.

Однако я получаю Resource not found for the segment 'root' при вызове ItemWithPath().

Насколько я понимаю, этот доступ к файлам относительно другого элемента должен работать в соответствии с документы по адресации на основе пути (и это работает для файлов/папок на пользовательском диске, но не для элементов внутри доля).

Является ли это ограничением и нужно ли мне хранить driveItemId для каждого общего файла, к которому я хочу получить доступ? Или есть более простое решение, чтобы я мог обрабатывать общие файлы так же, как файлы на диске пользователя?


person Philipp    schedule 28.09.2019    source источник


Ответы (1)


Действительно, похоже, что такая адресация на основе пути не поддерживается. Но вместо этого можно было бы рассмотреть следующие варианты

Вариант 1

Разделите один запрос на следующие подзапросы:

  • получить родительскую папку с помощью shareId: 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

Идея состоит в том, чтобы обращаться к элементу диска, создавая токен общего доступа для вложенной папки.
Учитывая реализацию кодирования общего 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);
}
person Vadim Gremyachev    schedule 29.09.2019
comment
к сожалению, вариант 2 работает только для учетных записей OneDrive для бизнеса. В моей личной учетной записи OneDrive WebUrl не создается из локального пути. - person Philipp; 03.10.2019
comment
@Philipp, действительно, вариант 2 в случае OneDrive Personal не кажется надежным - person Vadim Gremyachev; 03.10.2019