Durchblättern einer Sammlung mithilfe der Microsoft Graph SDKs
Artikel
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.
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.
headers := abstractions.NewRequestHeaders()
headers.Add("Prefer", "outlook.body-content-type=\"text\"")
var pageSize int32 = 10
query := users.ItemMessagesRequestBuilderGetQueryParameters{
Select: []string{"body", "sender", "subject"},
Top: &pageSize,
}
options := users.ItemMessagesRequestBuilderGetRequestConfiguration{
Headers: headers,
QueryParameters: &query,
}
result, err := graphClient.Me().Messages().Get(context.Background(), &options)
if err != nil {
log.Fatalf("Error getting messages: %v\n", err)
}
// Initialize iterator
pageIterator, err := graphcore.NewPageIterator[*models.Message](
result,
graphClient.GetAdapter(),
models.CreateMessageCollectionResponseFromDiscriminatorValue)
if err != nil {
log.Fatalf("Error creating page iterator: %v\n", err)
}
// Any custom headers sent in original request should also be added// to the iterator
pageIterator.SetHeaders(headers)
// Iterate over all pages
err = pageIterator.Iterate(
context.Background(),
func(message *models.Message)bool {
fmt.Printf("%s\n", *message.GetSubject())
// Return true to continue the iterationreturntrue
})
if err != nil {
log.Fatalf("Error iterating over messages: %v\n", err)
}
Java
ArrayList<Message> messages = new ArrayList<>();
MessageCollectionResponse messageResponse = graphClient.me().messages().get( requestConfiguration -> {
requestConfiguration.headers.add("Prefer", "outlook.body-content-type=\"text\"");
requestConfiguration.queryParameters.select = new String[] {"sender, subject, body"};
requestConfiguration.queryParameters.top = 10;
});
PageIterator<Message, MessageCollectionResponse> pageIterator =
new PageIterator.Builder<Message, MessageCollectionResponse>()
.client(graphClient)
// Response from the first request
.collectionPage(Objects.requireNonNull(messageResponse))
// Factory to create a new collection response
.collectionPageFactory(MessageCollectionResponse::createFromDiscriminatorValue)
// Used to configure subsequent requests
.requestConfigurator( requestInfo -> {
// Re-add the header and query parameters to subsequent requests
requestInfo.headers.add("Prefer", "outlook.body-content-type=\"text\"");
requestInfo.addQueryParameter("%24select", new String[] {"sender, subject, body"});
requestInfo.addQueryParameter("%24top", 10);
return requestInfo;
})
// Callback executed for each item in the collection
.processPageItemCallback( message -> {
messages.add(message);
returntrue;
}).build();
pageIterator.iterate();
PHP
$query = new MessagesRequestBuilderGetQueryParameters(
top: 10,
select: ['sender', 'subject', 'body']);
$config = new MessagesRequestBuilderGetRequestConfiguration(
queryParameters: $query,
headers: ['Prefer' => 'outlook.body-content-type="text"']);
$messages = $graphClient->me()
->messages()
->get($config)
->wait();
// Microsoft\Graph\Core\Tasks\PageIterator
$pageIterator = new PageIterator($messages, $graphClient->getRequestAdapter());
$callback = function($message): bool{
/** @var Models\Message $message */print($message->getSubject().PHP_EOL);
// Return true to continue iterationreturntrue;
};
// Re-add the header to subsequent requests
$pageIterator->setHeaders(['Prefer' => 'outlook.body-content-type="text"']);
$pageIterator->iterate($callback);
TypeScript
const response: PageCollection = await graphClient
.api('/me/messages?$top=10&$select=sender,subject,body')
.header('Prefer', 'outlook.body-content-type="text"')
.get();
// A callback function to be called for every item in the collection.// This call back should return boolean indicating whether not to// continue the iteration process.const callback: PageIteratorCallback = (message: Message) => {
console.log(message.subject);
returntrue;
};
// A set of request options to be applied to// all subsequent page requestsconst requestOptions: GraphRequestOptions = {
// Re-add the header to subsequent requests
headers: {
Prefer: 'outlook.body-content-type="text"',
},
};
// Creating a new page iterator instance with client a graph client// instance, page collection response from request and callbackconst pageIterator = new PageIterator(
graphClient,
response,
callback,
requestOptions,
);
// This iterates the collection until the nextLink is drained out.await pageIterator.iterate();
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.
$count = 0;
$messages = $graphClient->me()
->messages()
->get()
->wait();
// Microsoft\Graph\Core\Tasks\PageIterator
$pageIterator = new PageIterator($messages, $graphClient->getRequestAdapter());
$callback = function($message)use(&$count): bool{
/** @var Models\Message $message */
$count++;
print($count.'. '.$message->getSubject().PHP_EOL);
// Return true to continue iteration// Return false once first 5 have been processedreturn $count < 5;
};
$pageIterator->iterate($callback);
print('Pausing iteration after first 5'.PHP_EOL);
sleep(5);
// Process next 5
$count = 0;
$pageIterator->iterate($callback);
TypeScript
let count = 0;
const pauseAfter = 25;
const response: PageCollection = await graphClient
.api('/me/messages?$top=10&$select=sender,subject,body')
.get();
const callback: PageIteratorCallback = (message: Message) => {
console.log(message.subject);
count++;
// If we've iterated over the limit,// stop the iteration by returning falsereturn count < pauseAfter;
};
const pageIterator = new PageIterator(graphClient, response, callback);
await pageIterator.iterate();
while (!pageIterator.isComplete()) {
console.log('Iteration paused for 5 seconds...');
awaitnewPromise((resolve) => setTimeout(resolve, 5000));
// Reset count
count = 0;
await pageIterator.resume();
}
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 pageif (!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 loopbreak;
}
}
Erfahren Sie, wie Sie die E-Mails eines Benutzers in ASP.NET Core-Apps mit Microsoft Graph anzeigen können. Darüber hinaus erfahren Sie, wie Sie Microsoft Graph-Abfragen optimieren und E-Mails in Batches laden können.