Freigeben über


Verwenden der Microsoft Graph SDKs zum Batchen von Anforderungen

Batchverarbeitung ist eine Möglichkeit, mehrere Anforderungen in einer einzelnen HTTP-Anforderung zu kombinieren. Die Anforderungen werden in einer einzelnen JSON-Nutzlast kombiniert, die über POST an den \$batch Endpunkt gesendet wird. Microsoft Graph SDKs verfügen über eine Reihe von Klassen, um die Erstellung von Batchnutzlasten und das Analysieren von Batchantwortnutzlasten zu vereinfachen.

Wichtig

Aktuelle Einschränkungen bei der JSON-Batchverarbeitung in Microsoft Graph finden Sie unter Bekannte Probleme.

Erstellen einer Batchanforderung

Die Microsoft Graph SDKs bieten drei Klassen für die Arbeit mit Batchanforderungen und -antworten.

  • BatchRequestStep : Stellt eine einzelne Anforderung (z GET /me. B. ) innerhalb eines Batches dar. Es ermöglicht das Zuweisen eines eindeutigen Bezeichners zur Anforderung und das Angeben von Abhängigkeiten zwischen Anforderungen.
  • BatchRequestContent : Vereinfacht das Erstellen der Batchanforderungsnutzlast. Sie enthält mehrere BatchRequestStep-Objekte .
  • BatchResponseContent : Vereinfacht die Analyse der Antwort aus einer Batchanforderung. Es bietet die Möglichkeit, alle Antworten abzurufen, eine bestimmte Antwort nach ID abzurufen und die @odata.nextLink -Eigenschaft abzurufen, falls vorhanden.

Einfaches Batchverarbeitungsbeispiel

In diesem Beispiel wird gezeigt, wie mehrere Anforderungen in einem Batch gesendet werden, die nicht voneinander abhängig sind. Die Anforderungen können vom Dienst in beliebiger Reihenfolge ausgeführt werden. In diesem Beispiel wird der Benutzer und die Kalenderansicht des Benutzers für den aktuellen Tag abgerufen.

// Use the request builder to generate a regular
// request to /me
var userRequest = graphClient.Me.ToGetRequestInformation();

var today = DateTime.Now.Date;

// Use the request builder to generate a regular
// request to /me/calendarview?startDateTime="start"&endDateTime="end"
var eventsRequest = graphClient.Me.CalendarView
    .ToGetRequestInformation(requestConfiguration =>
        {
            requestConfiguration.QueryParameters.StartDateTime =
                today.ToString("yyyy-MM-ddTHH:mm:ssK");
            requestConfiguration.QueryParameters.EndDateTime =
                today.AddDays(1).ToString("yyyy-MM-ddTHH:mm:ssK");
        });

// Build the batch
var batchRequestContent = new BatchRequestContentCollection(graphClient);

// Using AddBatchRequestStepAsync adds each request as a step
// with no specified order of execution
var userRequestId = await batchRequestContent
    .AddBatchRequestStepAsync(userRequest);
var eventsRequestId = await batchRequestContent
    .AddBatchRequestStepAsync(eventsRequest);

var returnedResponse = await graphClient.Batch.PostAsync(batchRequestContent);

// De-serialize response based on known return type
try
{
    var user = await returnedResponse
        .GetResponseByIdAsync<User>(userRequestId);
    Console.WriteLine($"Hello {user.DisplayName}!");
}
catch (Exception ex)
{
    Console.WriteLine($"Get user failed: {ex.Message}");
}

// For collections, must use the *CollectionResponse class to deserialize
// The .Value property will contain the *CollectionPage type that the Graph client
// returns from GetAsync().
try
{
    var events = await returnedResponse
        .GetResponseByIdAsync<EventCollectionResponse>(eventsRequestId);
    Console.WriteLine(
        $"You have {events.Value?.Count} events on your calendar today.");
}
catch (Exception ex)
{
    Console.WriteLine($"Get calendar view failed: {ex.Message}");
}

Batches mit abhängigen Anforderungen

In diesem Beispiel wird gezeigt, wie mehrere Anforderungen in einem Batch gesendet werden, die voneinander abhängig sind. Die Anforderungen werden vom Dienst in der von den Abhängigkeiten angegebenen Reihenfolge ausgeführt. In diesem Beispiel wird dem Kalender des Benutzers ein Ereignis mit einer Startzeit während des aktuellen Tages hinzugefügt und die Kalenderansicht des Benutzers für den aktuellen Tag abgerufen. Um sicherzustellen, dass die zurückgegebene Kalenderüberprüfung das neu erstellte Ereignis enthält, wird die Anforderung für die Kalenderansicht als abhängig von der Anforderung zum Hinzufügen des neuen Ereignisses konfiguriert. Dadurch wird sichergestellt, dass die Anforderung zum Hinzufügen von Ereignissen zuerst ausgeführt wird.

Hinweis

Wenn bei der Anforderung zum Hinzufügen eines Ereignisses ein Fehler auftritt, schlägt die Anforderung zum Abrufen der Kalenderansicht mit einem 424 Failed Dependency Fehler fehl.

var today = DateTime.Now.Date;

var newEvent = new Event
{
    Subject = "File end-of-day report",
    Start = new DateTimeTimeZone
    {
        // 5:00 PM
        DateTime = today.AddHours(17)
            .ToString("yyyy-MM-ddTHH:mm:ss"),
        TimeZone = TimeZoneInfo.Local.StandardName,
    },
    End = new DateTimeTimeZone
    {
        // 5:30 PM
        DateTime = today.AddHours(17).AddMinutes(30)
            .ToString("yyyy-MM-ddTHH:mm:ss"),
        TimeZone = TimeZoneInfo.Local.StandardName,
    },
};

// Use the request builder to generate a regular
// POST request to /me/events
var addEventRequest = graphClient.Me.Events
    .ToPostRequestInformation(newEvent);

// Use the request builder to generate a regular
// request to /me/calendarview?startDateTime="start"&endDateTime="end"
var calendarViewRequest = graphClient.Me.CalendarView.ToGetRequestInformation(
    requestConfiguration =>
    {
        requestConfiguration.QueryParameters.StartDateTime =
            today.ToString("yyyy-MM-ddTHH:mm:ssK");
        requestConfiguration.QueryParameters.EndDateTime =
            today.AddDays(1).ToString("yyyy-MM-ddTHH:mm:ssK");
    });

// Build the batch
var batchRequestContent = new BatchRequestContentCollection(graphClient);

// Force the requests to execute in order, so that the request for
// today's events will include the new event created.

// First request, no dependency
var addEventRequestId = await batchRequestContent
    .AddBatchRequestStepAsync(addEventRequest);

// Second request, depends on addEventRequestId
var eventsRequestId = Guid.NewGuid().ToString();
var eventsRequestMessage = await graphClient.RequestAdapter
    .ConvertToNativeRequestAsync<HttpRequestMessage>(calendarViewRequest);
batchRequestContent.AddBatchRequestStep(new BatchRequestStep(
    eventsRequestId,
    eventsRequestMessage,
    [addEventRequestId]));

var returnedResponse = await graphClient.Batch.PostAsync(batchRequestContent);

// De-serialize response based on known return type
try
{
    var createdEvent = await returnedResponse
        .GetResponseByIdAsync<Event>(addEventRequestId);
    Console.WriteLine($"New event created with ID: {createdEvent.Id}");
}
catch (Exception ex)
{
    Console.WriteLine($"Add event failed: {ex.Message}");
}

// For collections, must use the *CollectionResponse class to deserialize
// The .Value property will contain the *CollectionPage type that the Graph client
// returns from GetAsync().
try
{
    var events = await returnedResponse
        .GetResponseByIdAsync<EventCollectionResponse>(eventsRequestId);
    Console.WriteLine(
        $"You have {events.Value?.Count} events on your calendar today.");
}
catch (Exception ex)
{
    Console.WriteLine($"Get calendar view failed: {ex.Message}");
}