OneDrive API でフォルダ内のアイテムを 200 個以上列挙する

Page creation date :

The page you are currently viewing does not support the selected display language.

動作確認環境

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

動作必須環境

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

一度に取得できるアイテムの上限数

OneDrive API でフォルダの内容一覧を取得した際、一度に取得できる最大数は 200 までとなっています。 この数値は以下の公式サイトにも記載されています。

これは URL を直接叩いた場合でもそうですが Microsoft.Graph のライブラリを使用した場合でも同様です。 以前の Tips に記載していた以下のコードでも 200 件までしか取得されません。 エラーなどは発生しませんが、DriveItemCollectionResponse.OdataNextLink プロパティに値が設定されているかどうかで 201件以上アイテムが存在するか確認できます。

// フォルダ内アイテム一覧取得
var folderChildren = await graphClient.Drives[drive.Id].Items[folderItem.Id].Children.GetAsync();
if (folderChildren == null || folderChildren.Value == null)
{
  Console.WriteLine("フォルダの一覧を取得できませんでした。");
  return;
}
foreach (var item in folderChildren.Value)
{
  Console.WriteLine($"Type={(item.File != null ? "File" : "Folder")}, Id={item.Id}, Name={item.Name}, Size={item.Size}");
}

HTTP リクエストで取得する場合は @odata.nextLink の URL に逐一アクセスして取得する必要がありますが、 Microsoft.Graph のライブラリを使用している場合はより簡単に 200 件を超えるアイテム全てを取得する方法があります。 PageIterator というクラスが用意されているのでそれを使用するだけです。以下のように使用します。

// フォルダ内アイテム一覧取得
var folderChildren = await graphClient.Drives[drive.Id].Items[folderItem.Id].Children.GetAsync();
if (folderChildren == null || folderChildren.Value == null)
{
  Console.WriteLine("フォルダの一覧を取得できませんでした。");
  return;
}

var pageIterator = PageIterator<DriveItem, DriveItemCollectionResponse>.CreatePageIterator(
      graphClient,
      folderChildren,
      (item) =>
      {
        Console.WriteLine($"Type={(item.File != null ? "File" : "Folder")}, Id={item.Id}, Name={item.Name}, Size={item.Size}");
        return true;  // false を返すまで次のアイテムを列挙します
      });
await pageIterator.IterateAsync();

フォルダアイテム一覧レスポンス (DriveItemCollectionResponse) を取得したら PageIterator.CreatePageIterator メソッドの第2引数に指定します。 第3引数がコールバックになっておりアイテム単位で呼ばれるのでこれをリスト化するなりすれば全てのアイテムを取得できるはずです。

ちなみに PageIterator.CreatePageIterator はイテレーションを生成しているだけなので最後に PageIterator.IterateAsync メソッドを呼ぶ必要があります。