Freigeben über


Durchblättern einer Sammlung mithilfe der Microsoft Graph SDKs

Aus Leistungsgründen werden Sammlungen von Entitäten häufig in Seiten aufgeteilt, und jede Seite wird mit einer URL zur nächsten Seite zurückgegeben. Die PageIterator-Klasse vereinfacht die Nutzung von ausgelagerten Sammlungen. PageIterator verarbeitet das Aufzählen der aktuellen Seite und das automatische Anfordern nachfolgender Seiten.

Alternativ können Sie die @odata.nextLink -Eigenschaft verwenden, um nachfolgende Seiten manuell anzufordern.

Anforderungsheader

Wenn Sie zusätzliche Anforderungsheader in Ihrer ursprünglichen Anforderung senden, werden diese Header nicht standardmäßig in nachfolgenden Seitenanforderungen eingeschlossen. Wenn diese Header bei nachfolgenden Anforderungen gesendet werden müssen, müssen Sie sie explizit festlegen.

Durchlaufen aller Nachrichten

Das folgende Beispiel zeigt das Durchlaufen aller Nachrichten im Postfach eines Benutzers.

Tipp

In diesem Beispiel wird eine kleine Seitengröße mit dem top -Parameter zu Demonstrationszwecken festgelegt. Sie können die Seitengröße auf 999 festlegen, um die Anzahl der erforderlichen Anforderungen zu minimieren.

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();

Beenden und Fortsetzen der Iteration

Einige Szenarien erfordern das Beenden des Iterationsprozesses, um andere Aktionen ausführen zu können. Es ist möglich, die Iteration anzuhalten, indem vom Iterationsrückruf zurückgegeben false wird. Die Iteration kann fortgesetzt werden, indem die resume -Methode für den PageIterator aufgerufen wird.

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();
}

Manuelles Anfordern nachfolgender Seiten

Als Alternative zur Verwendung der PageIterator-Klasse können Sie die Antwort für eine @odata.nextLink Eigenschaft manuell überprüfen und die nächste Seite anfordern.

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;
    }
}

Fehlerbehandlung

Vermeiden von DirectoryPageTokenNotFoundException-Fehlern

Beim Paginieren großer Datenmengen tritt möglicherweise der Fehler auf, der DirectoryPageTokenNotFoundException verhindert, dass die Client-App nachfolgende Seiten erfolgreich abruft. Dieser Fehler tritt auf, wenn die Client-App ein Token aus einem Wiederholungsvorgang verwendet, um die nächste Ergebnisseite anzufordern.

Um diesen Fehler zu vermeiden, verwenden Sie keine Token aus Wiederholungsvorgängen für nachfolgende Seitenanforderungen, da diese Token nicht garantiert für zukünftige Anforderungen gültig sind. Speichern Sie stattdessen das Token aus der letzten erfolgreichen Antwort, und verwenden Sie es für die nächste Seitenanforderung. Daher sollte der @odata.nextLink für die Wiederholung verwendete Wert für die nachfolgende Seitenanforderung verwendet werden.

Beispielszenario

  1. Rufen Sie Seite 1 ab, und erhalten Sie das Token "Token1".
  2. Verwenden Sie "Token1", um Seite 2 anzufordern.
  3. Wenn ein Netzwerkfehler auftritt, wiederholen Sie die Anforderung.
  4. Während des Wiederholungsversuchs erhalten Sie das neue Token "RetryToken".
  5. Verwenden Sie "RetryToken" nicht, um Seite 3 anzufordern, da dies den DirectoryPageTokenNotFoundException Fehler verursachen kann.
  6. Verwenden Sie stattdessen "Token1" (das Token aus der letzten erfolgreichen Antwort ohne Wiederholung), um Seite 3 anzufordern.