Как легко работать с OneDrive из приложений UWP

c647811e17c0401c839bea10679b3afa.jpg

Продолжаю рассказывать об интересных/полезных вещах из мира XAML/C# приложений UWP. OneDrive API является частью Microsoft Graph. Для работы с OneDrive можно использовать OneDrive REST API, которое использует протокол HTTP и в частности его методы GET, POST, DELETE, PUT…

Кроме того, в соответствии с новыми принципами работы Microsoft, была создана библиотека обертка OneDrive SDK for CSharp, которая облегчает работу и использование сервиса из кода ваших приложений.

OneDrive SDK for CSharp — это Portable Class Library (PCL) которая предназначена для следующих типов проектов:

.NET 4.5.1
.NET for Windows Store apps
Windows Phone 8.1 and higher

Для того чтобы установить SDK можно выполнить команду в консоли диспетчера пакетов NuGet

Install-Package Microsoft.OneDriveSDK

или в VS менеджере NuGet воспользоваться поиском по фразе Microsoft.OneDriveSDK

После создания универсального приложения необходимо его связать с магазином Windows. Таким образом оно автоматически будет зарегистрировано в группе приложений Live SDK. По адресу https://apps.dev.microsoft.com/#/appList можно проверить, что приложение зарегистрировано в группе Live SDK applications. Насколько я понял, все приложения Windows Store по умолчанию попадают в эту группу.

Аутентификация происходит с помощью нескольких строчек кода:

    string[] scopes = { "wl.signin", "onedrive.readwrite" };
    IOneDriveClient _client = OneDriveClientExtensions.GetClientUsingOnlineIdAuthenticator(scopes);
    await _client.AuthenticateAsync();

Все права/разрешения (scopes) доступны по ссылке: Authentication scopes

При аутентификации открывается новое окно, в котором пользователь сможет ввести свои данные:

fd1783dae16a46c2817dcbb9672f37f3.PNG

Выйти можно с помощью следующего кода:

await _client.SignOutAsync();

Приведу самые типичные операции с файлами. Скачать файл можно с помощью вот такого сниппета:
    string[] scopes = { "wl.signin", "onedrive.readwrite" };
    IOneDriveClient _client = OneDriveClientExtensions.GetClientUsingOnlineIdAuthenticator(scopes);
    AccountSession session = await _client.AuthenticateAsync();

    if (!_client.IsAuthenticated) return;

    Item item = await _client
             .Drive
             .Root
             .ItemWithPath("CodeExamples/MyDemo.zip")
             .Request()
             .GetAsync();

    using (Stream contentStream = await _client
                       .Drive
                       .Items[item.Id]
                       .Content
                       .Request()
                       .GetAsync())
    {
        StorageFile file = await ApplicationData.Current.LocalFolder.
                                            CreateFileAsync("MyDemo.zip", CreationCollisionOption.OpenIfExists);

        using (Stream outputstream = await file.OpenStreamForWriteAsync())
        {
            await contentStream.CopyToAsync(outputstream);
        }
    }

А загрузить с помощью такого:

    string[] scopes = { "wl.signin", "onedrive.readwrite" };
    IOneDriveClient _client = OneDriveClientExtensions.GetClientUsingOnlineIdAuthenticator(scopes);
    AccountSession acse = await _client.AuthenticateAsync();

    if (!_client.IsAuthenticated) return;

    FileOpenPicker fileOpenPicker = new FileOpenPicker();
    fileOpenPicker.FileTypeFilter.Add(".jpg");
    StorageFile file = await fileOpenPicker.PickSingleFileAsync();

    if (file != null)
    {
        using (Stream contentStream = await file.OpenStreamForReadAsync())
        {
            var uploadedItem = await _client
                                         .Drive
                                         .Root
                                         .ItemWithPath("CodeExamples/" + file.Name)
                                         .Content
                                         .Request()
                                         .PutAsync(contentStream);
        }
    }

Описание других операций с файлами доступно по ссылке на GitHub: Items in the OneDrive SDK for C#

А вот таким образом можно получить список элементов в корневой папке:

    IChildrenCollectionPage ic=  await _client
           .Drive
           .Root
           .Children
           .Request()
           .GetAsync();

Теперь давайте немного рассмотрим эту же операцию, но уже с помощью REST API. Для этого нам понадобится Access Token, который мы можем получить из объекта активной сессии — AccountSession (используем возможности OneDrive SDK для упрощения работы с REST API). И еще понадобится класс HttpClient из пространства System.Net.Http:
    Uri uri = new Uri("https://api.onedrive.com/v1.0/drive/root/children");
    HttpClient client = new HttpClient();
    client.DefaultRequestHeaders.Authorization =
                                            new AuthenticationHeaderValue("Bearer", session.AccessToken);
    string jsonstring = await client.GetStringAsync(uri);

В результате получим строку в виде JSON с перечислением всех находящихся на OneDrive в корневой папке элементов.
Вы можете не регистрировать приложение в Store, а получить временный Access Token (действительный в течение часа) для экспериментов. Для этого необходимо на страничке OneDrive authentication and sign-in нажать кнопку Get Token.

Первый способ очевидно проще и короче, но второй тоже может быть полезен. Скажем, можно получить ссылку на файл вот так:

    Uri uri = new Uri("https://api.onedrive.com/v1.0/drive/root:/CodeExamples/MyDemo.zip:/action.createLink");
    HttpClient client = new HttpClient();
    client.DefaultRequestHeaders.Authorization =
                                            new AuthenticationHeaderValue("Bearer", session.AccessToken);

    var requestJson = JsonConvert.SerializeObject( new RequestLinkInfo { type = "view" });
    var content = new StringContent(requestJson,Encoding.UTF8,"application/json");
    var response = await client.PostAsync(uri,content);

    LinkResponseInfo result = JsonConvert.DeserializeObject(
                                                                        await response.Content.ReadAsStringAsync());

Рассматривая контент, вы можете заметить, что в строке Uri путь к файлу обрамлен двоеточием. Альтернативно можно использовать id файла /drive/items/{item-id}/action.createLink.

Для сериализации и десериализации JSON-а нам понадобятся следующие классы:

  public class RequestLinkInfo
    {
        public string type { get; set; }  // возможные значения: view, edit или embed
        public string scope { get; set; } // optional - возможные значения: anonymous или organization
    }

    public class LinkResponseInfo
    {
        public string id { get; set; }
        public string[] roles { get; set; }
        public Link link { get; set; }
    }

    public class Link
    {
        public string type { get; set; }
        public string scope { get; set; }
        public string webUrl { get; set; }
        public OneDriveApplication application { get; set; }
    }

    public class OneDriveApplication
    {
        public string id { get; set; }
        public string displayName { get; set; }
    }

Сам URL можно будет получить из объекта result:
    string fileurl = result.link.webUrl;

Что интересно, так это то, что можно даже использовать старенький Live API и получить доступ к информации о том пользователе, который залогинился:
    Uri uri = new Uri("https://apis.live.net/v5.0/me");
    HttpClient client = new HttpClient();
    client.DefaultRequestHeaders.Authorization =
                                            new AuthenticationHeaderValue("Bearer", session.AccessToken);
    string jsonstring = await client.GetStringAsync(uri); 

Хотя, как долго Live API еще будет доступно сказать сложно.
Официальная документация доступна здесь: Develop with the OneDrive API

Комментарии (0)

© Habrahabr.ru