次の方法で共有


Microsoft Graph SDK を使用してコレクションをページ表示する

パフォーマンス上の理由から、エンティティのコレクションはページに分割されることが多く、各ページには次のページへの URL が返されます。 PageIterator クラスを使用すると、ページコレクションの使用が簡略化されます。 PageIterator は、現在のページの列挙と後続のページの要求を自動的に処理します。

または、 @odata.nextLink プロパティを使用して 、後続のページを手動で要求することもできます。

要求ヘッダー

最初の要求で追加の要求ヘッダーを送信する場合、これらのヘッダーは、後続のページ要求に既定では含まれません。 これらのヘッダーを後続のリクエストで送信する必要がある場合は、明示的に設定する必要があります。

すべてのメッセージを反復処理する

次の例は、ユーザーのメールボックス内のすべてのメッセージを反復処理する方法を示しています。

ヒント

次の使用例は、デモンストレーションのために top パラメーターを使用して小さなページ サイズを設定します。 ページ サイズを最大 999 に設定して、必要な要求の数を最小限に抑えることができます。

var messages = await graphClient.Me.Messages
    .GetAsync(requestConfiguration =>
    {
        requestConfiguration.QueryParameters.Top = 10;
        requestConfiguration.QueryParameters.Select =
            ["sender", "subject", "body"];
        requestConfiguration.Headers.Add(
            "Prefer", "outlook.body-content-type=\"text\"");
    });

if (messages == null)
{
    return;
}

var pageIterator = PageIterator<Message, MessageCollectionResponse>
    .CreatePageIterator(
        graphClient,
        messages,
        // Callback executed for each item in
        // the collection
        (msg) =>
        {
            Console.WriteLine(msg.Subject);
            return true;
        },
        // Used to configure subsequent page
        // requests
        (req) =>
        {
            // Re-add the header to subsequent requests
            req.Headers.Add("Prefer", "outlook.body-content-type=\"text\"");
            return req;
        });

await pageIterator.IterateAsync();

イテレーションの停止と再開

一部のシナリオでは、他のアクションを実行するためにイテレーション プロセスを停止する必要があります。 イテレーション コールバックから false を返すことで、イテレーションを一時停止できます。 PageIteratorresume メソッドを呼び出すことで、イテレーションを再開できます。

int count = 0;
int pauseAfter = 25;

var messages = await graphClient.Me.Messages
    .GetAsync(requestConfiguration =>
    {
        requestConfiguration.QueryParameters.Top = 10;
        requestConfiguration.QueryParameters.Select =
            ["sender", "subject"];
    });

if (messages == null)
{
    return;
}

var pageIterator = PageIterator<Message, MessageCollectionResponse>
    .CreatePageIterator(
        graphClient,
        messages,
        (msg) =>
        {
            Console.WriteLine(msg.Subject);
            count++;
            // If we've iterated over the limit,
            // stop the iteration by returning false
            return count < pauseAfter;
        });

await pageIterator.IterateAsync();

while (pageIterator.State != PagingState.Complete)
{
    Console.WriteLine("Iteration paused for 5 seconds...");
    await Task.Delay(5000);
    // Reset count
    count = 0;
    await pageIterator.ResumeAsync();
}

後続のページを手動で要求する

PageIterator クラスを使用する代わりに、@odata.nextLink プロパティの応答を手動でチェックし、次のページを要求できます。

var messages = await graphClient.Me.Messages
    .GetAsync(requestConfiguration =>
    {
        requestConfiguration.QueryParameters.Top = 10;
    });

while (messages?.Value != null)
{
    foreach (var message in messages.Value)
    {
        Console.WriteLine(message.Subject);
    }

    // If OdataNextLink has a value, there is another page
    if (!string.IsNullOrEmpty(messages.OdataNextLink))
    {
        // Pass the OdataNextLink to the WithUrl method
        // to request the next page
        messages = await graphClient.Me.Messages
            .WithUrl(messages.OdataNextLink)
            .GetAsync();
    }
    else
    {
        // No more results, exit loop
        break;
    }
}

エラー処理

DirectoryPageTokenNotFoundException エラーの回避

大量のデータ セットをページングするときに、 DirectoryPageTokenNotFoundException エラーが発生し、クライアント アプリが後続のページを正常に取得できなくなる可能性があります。 このエラーは、クライアント アプリが再試行操作のトークンを使用して結果の次のページを要求するときに発生します。

このエラーを回避するには、後続のページ要求に対して再試行操作のトークンを使用しないでください。これらのトークンは、将来の要求に対して有効であることが保証されていないためです。 代わりに、最後に成功した応答のトークンを保持し、次のページ要求に使用します。 したがって、再試行に使用される @odata.nextLink 値は、後続のページ要求に使用する必要があります。

シナリオ例

  1. ページ 1 を取得し、トークン "Token1" を受け取ります。
  2. "Token1" を使用してページ 2 を要求します。
  3. ネットワーク エラーが発生した場合は、要求を再試行してください。
  4. 再試行中に、新しいトークン "RetryToken" を受け取ります。
  5. "RetryToken" を使用してページ 3 を要求しないでください。これは、 DirectoryPageTokenNotFoundException エラーが発生する可能性があるためです。
  6. 代わりに、"Token1" (最後に成功した非再試行応答のトークン) を使用して、ページ 3 を要求します。