Поделиться через


Использование пакетов SDK Microsoft Graph для пакетных запросов

Пакетная обработка — это способ объединения нескольких запросов в один HTTP-запрос. Запросы объединяются в одну полезную нагрузку JSON, которая отправляется через POST в конечную точку \$batch . Пакеты SDK Microsoft Graph имеют набор классов, упрощающих создание полезных данных пакетной службы и анализ полезных данных пакетного ответа.

Важно!

Текущие ограничения пакетной обработки JSON в Microsoft Graph см. в разделе Известные проблемы.

Создание пакетного запроса

Пакеты SDK Для Microsoft Graph предоставляют три класса для работы с пакетными запросами и ответами.

  • BatchRequestStep — представляет один запрос (например, GET /me) в пакете. Он позволяет назначать уникальный идентификатор запросу и указывать зависимости между запросами.
  • BatchRequestContent — упрощает создание полезных данных пакетного запроса. Он содержит несколько объектов BatchRequestStep .
  • BatchResponseContent — упрощает синтаксический анализ ответа из пакетного запроса. Он позволяет получить все ответы, получить конкретный ответ по идентификатору @odata.nextLink и получить свойство, если оно имеется.

Простой пример пакетной обработки

В этом примере показано, как отправить несколько запросов в пакете, которые не зависят друг от друга. Запросы могут выполняться службой в любом порядке. В этом примере получается пользователь и представление календаря пользователя на текущий день.

// 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}");
}

Пакеты с зависимыми запросами

В этом примере показано, как отправить несколько запросов в пакете, которые зависят друг от друга. Запросы будут выполняться службой в порядке, указанном зависимостями. В этом примере в календарь пользователя добавляется событие с временем начала в течение текущего дня и возвращается представление календаря пользователя за текущий день. Чтобы убедиться, что возвращенная проверка календаря включает созданное событие, запрос для представления календаря настраивается как зависящий от запроса на добавление нового события. Это гарантирует, что запрос на добавление события будет выполнен первым.

Примечание.

Если запрос на добавление события завершается ошибкой, запрос на получение представления календаря завершится ошибкой 424 Failed Dependency .

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