OneDrive API をバッチプログラムなどユーザー操作なしで使用する (.NET C# 版) (Microsoft Graph ライブラリ使用)

ページ作成日 :

動作確認環境

Visual Studio
  • Visual Studio 2022
.NET
  • .NET 8
Microsoft 認証 API
  • 2.0 OAuth 2
Microsoft OneDrive API
  • 1.0
Microsoft.Graph
  • 5.54.0
Microsoft アカウントの種類
  • 職場または学校アカウント

動作必須環境

Visual Studio
  • いずれかのバージョン
ASP.NET Core
  • いずれかのバージョン
Microsoft 認証 API
  • 2.0 OAuth 2
Microsoft OneDrive API
  • 1.0
Microsoft.Graph
  • 5.XX
Microsoft アカウントの種類
  • 職場または学校アカウント

この Tips について

この Tips は以下の Tips をベースに Microsoft Graph のライブラリを使用した形にプログラムを直したものです。 なので概要や Azure 上での操作手順は以下の Tips の手順を参考にし、プログラム構築になったらこの Tips を参照してください。

前提条件

  • 「職場または学校アカウント」の Microsoft アカウントを登録済みであること
  • 上記 Microsoft アカウントに紐づく OneDrive が使用できること (OneDrive Business など)
  • Visual Studio 2022 がインストールされていること
  • 上記の Tips を参考に Azure 上で「アプリの登録」を行い ID など必要な情報を取得済みであること

コンソールアプリケーションを作成する

Visual Studio を起動してコンソールアプリケーションのプロジェクトを作成します。 Visual Studio 以外で作ってもよいですがここでは Visual Studio で説明します。

場所やプロジェクト名などは任意です。ここではプロジェクト名を OneDriveApiDotNetClientCredentialsMicrosoftGraph としています。

まずは Microsoft.GraphAzure.Identity のライブラリを NuGet で取得します。

今回コード分けなどはせず Program.cs に上からずらずら記述するので動きを確認出来たら必要に応じてコードを分けるなど書き換えてください。

using Azure.Identity;
using Microsoft.Graph;

使用する名前空間を記述します。

// 各種 ID などの定義
var clientId = "XXXXXXXX";      // クライアント ID
var tenantId = "XXXXXXXX";      // テナント ID
var clientSecret = "XXXXXXXX";  // クライアント シークレット
var userId = "XXXXXXXX";        // ユーザー ID

それぞれ Azure 上で取得した ID などをセットしてください。

// 使いまわすので最初に定義しておく
HttpClient httpClient = new();

指定した URL に対してリクエストするための HttpClient を生成しておきます。

// クライアント シークレットによる認証情報を定義
ClientSecretCredential clientSecretCredential = new(tenantId, clientId, clientSecret);

// HttpClient と認証情報で Microsoft Graph サービスのクライアントを生成
using GraphServiceClient graphClient = new(httpClient, clientSecretCredential);

取得した ID などを使用してクライアント シークレットを定義します。 そのデータと HttpClient を使用して GraphServiceClient のインスタンスを生成することができます。 各種 API にアクセスするときはこの GraphServiceClient を使うことが多いです。

// 対象ユーザーに紐づく OneDrive を取得 (紐づいているドライブが OneDrive 1つという前提)
var drive = await graphClient.Users[userId].Drive.GetAsync();
if (drive == null)
{
  Console.WriteLine("ドライブを取得できませんでした。");
  return;
}

GraphServiceClient を使用してまずはユーザーに紐づく OneDrive を取得します。 複数のドライブが紐づいている場合は Drives から対象の OneDrive を探して取得します。 もしかしたら OneDrive 以外のドライブも紐づいている可能性がありますがそこまでは確認していません。 OneDrive がひとつのみ紐づいていることを確認しているのであれば Drive プロパティでそのまま取得して問題ありません。

// OneDrive のルートを取得
var root = await graphClient.Drives[drive.Id].Root.GetAsync();
if (root == null)
{
  Console.WriteLine("OneDrive のルートを取得できませんでした。");
  return;
}

OneDrive を取得したら後は自由に OneDrive にアクセスできます。 フォルダやファイルの ID などを調べているのであれば直接指定することができますが、 まずは何も調べていない状態なのでルートフォルダを取得しています。

// ルート直下にあるフォルダ一覧取得
var rootChildren = await graphClient.Drives[drive.Id].Items[root.Id].Children.GetAsync();
if (rootChildren == null || rootChildren.Value == null)
{
  Console.WriteLine("フォルダの一覧を取得できませんでした。");
  return;
}
foreach (var item in rootChildren.Value)
{
  Console.WriteLine($"Type={(item.File != null ? "File" : "Folder")}, Id={item.Id}, Name={item.Name}, Size={item.Size}");
}

ルートフォルダを取得したら Children で直下にあるファイル・フォルダ一覧を取得できます。 あとは取得した値を列挙して名前を表示するようにしています。

まとめ

「Microsoft Graph」のライブラリを使用してコードを作成してみました。 API の URL にアクセスする方法に比べてかなりコードの量を減らすことができると思います。

ただデメリットとしてはライブラリのバージョンによってコードに破壊的変更が生まれる可能性があるのとドキュメントが少ない点があげられると思います。 これらを許容できるのであれば書くコード量が減るこちらのほうがメリットがあるのではないかと思います。

謝辞

今回 OneDrive API を使用するにあたりいくつか不明点があったので質問させていただきました。