Как легко работать с OneDrive из приложений UWP
Продолжаю рассказывать об интересных/полезных вещах из мира 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
При аутентификации открывается новое окно, в котором пользователь сможет ввести свои данные:
Выйти можно с помощью следующего кода:
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