OneDrive est le service de Microsoft permettant de stocker des fichiers. Pour les développeut OneDrive est accessible via une API REST. Pour utiliser cette API, Microsoft fournit un SDK pour accéder à cette API depuis une application Desktop, WinRT, JavaScript, Android ou iOS. On pourrait donc se dire intuitivement qu’il n’y a plus rien à coder mais la réalité est autre… Le SDK permet en fait de s’authentifier et d’effectuer des requêtes HTTP. Cependant elle ne contient pas de méthode du type “GetFiles”, “CreateDirectory” ou “UploadFile”.
Ayant besoin d’automatiser certains traitement avec OneDrive, j’ai créé un client en .NET. Avant de montrer son fonctionnement, il est accessible sur GitHub : https://github.com/meziantou/Meziantou.OneDrive. Pour information il ne repose pas sur le Live SDK.
Enregistrer l’application
Pour utiliser l’API de OneDrive, il faut enregistrer l’application sur https://account.live.com/developers/applications.
Comme dans notre cas il s’agit d’une application desktop, il faut l’indiquer :
Au final on obtient le ClientId :
Authentifier l’utilisateur
Pour s’authentifier OneDrive utilise OAuth. Il faut donc ouvrir un web browser sur la page de login et récupérer le jeton d’accès une fois l’utilisateur. Pour cela on utilise la méthode suivante :
LiveSession session = await Meziantou.OneDrive.AuthenticationForm.CreateSessionAsync(
clientId,
new[]
{
Scope.BasicProfile,
Scope.Photos,
Scope.ReadOnly,
Scope.ReadWrite,
Scope.SharedItems,
Scope.OfflineAccess
}, refreshTokenHandler /* may be null */);
Voici les écrans affichés à l’utilisateur :
Lors de l’authentification, on récupère le jeton d’accès à l’API (Access Token). Ce jeton expire au bout d’un certain temps. Pour éviter à l’utilisateur de se ré-authentifier on a également un Refresh Token. Ce deuxième jeton permet de générer un nouveau jeton d’accès sans intéraction avec l’utilisateur. En spécifiant un conteneur pour le refresh token (non obligatoire), le processus de regénération est automatisé. Par défaut 2 handlers sont disponibles :
- InMemory : Le jeton est stocké en mémoire et est donc supprimé dès que l’application est terminée.
- CredentialManager : Le jeton est stocké dans le Credential Manager et est donc accessible même après redémarrage de la machine.
Une fois l’objet LiveSession créé, on peut créer le client OneDrive :
OneDriveClient client = new OneDriveClient(session);
Lister les items (Fichiers et Dossiers)
OneDriveFolder root = await client.GetOneDriveRootAsync(cancellationToken);
foreach (OneDriveItem child in await root.GetChildrenAsync(cancellationToken))
{
Console.WriteLine(string.Format("({0}) {1}", child.Type, child.Name));
}
// Pagination
root.GetChildrenAsync(new GetOptions { Offset = 0, Limit = 20 }, cancellationToken)
// Filter
root.GetChildrenAsync(new GetOptions { Filters = ItemTypeFilter.Folder | ItemTypeFilter.Album }, cancellationToken)
// Search
client.SearchAsync("sample", cancellationToken)
// Well-known folders
client.GetWellKnownFolderAsync(WellKnownFolder.CameraRoll, cancellationToken)
client.GetWellKnownFolderAsync(WellKnownFolder.Documents, cancellationToken)
client.GetWellKnownFolderAsync(WellKnownFolder.Pictures, cancellationToken)
client.GetWellKnownFolderAsync(WellKnownFolder.PublicDocuments, cancellationToken)
Create a folder
OneDriveFolder newFolder = await root.CreateChildDirectoryAsync("New Folder", cancellationToken)
Télécharger un fichier
Stream stream = await file.DownloadAsync(cancellationToken)
Il est possible de reprendre le téléchargement en spécifier le range à télécharger :
Stream stream = await file.DownloadAsync(rangeStart: 0, rangeEnd: 100, cancellationToken) // range in bytes
Uploader un fichier
Pour uploader un fichier l’API fournit 2 méthodes : l’API REST et BITS. L’API REST limite la taille du fichier à environ 100MO. BITS nécessite au minimum 3 requêtes par envoie de fichier mais permet d’envoyer le fichier morceau par morceau avec reprise de l’envoie en cas d’erreur.
// using REST API (max file size: about 100MB)
OneDriveFile file = await oneDriveFolder.UploadAsync(fileInfo, OverwriteOption.Overwrite, cancellationToken);
// using BITS (simple)
OneDriveFile file = await oneDriveFolder.BitsUploadAsync(fileInfo, cancellationToken);
// using BITS (with retry)
EventHandler<BitsUploadChunckFailedEventArgs> callback = (sender, args) =>
{
args.Cancel = args.Attempt > maximumRetryCount;
};
oneDriveFile = await folder.BitsUploadAsync(fileInfo, chunckSize, callback, cancellationToken));
Conclusion
C’est une présentation sommaire des possibilités. D’autres méthodes existent pour notamment pour déplacer des fichiers ou dossiers, connaitre l’espace de stockage restant, ou encore obtenir des liens de partage.
Le code est accessible sur GitHub : https://github.com/meziantou/Meziantou.OneDrive.