Microsoft Graph Batch Stream Photos

Viewed 368

How can I batch Photo requests using BatchRequestContent in Microsoft.Graph? Calling the Photos endpoint for each staff member takes too long so I need to batch the requests together. I have successfully used batching for other requests but not for Photos Stream.

My code throws an exception when calling await batchResponse.GetResponseByIdAsync<Stream>(id.Value)

Exception: Error parsing comment. Expected: *, got 9. Path '', line 1, position 1.

Full code:

private async Task QueryStaffPhotos(GraphServiceClient client, IList<StaffMember> staffMembers)
{
    BatchRequestContent content = new BatchRequestContent();
    int count = 0, currentBatch = 0;
    IDictionary<string, string> batchResponseIds = new Dictionary<string, string>();
    int total = staffMembers.Count(c => c.HasPhoto);
    foreach (StaffMember member in staffMembers.Where(c => c.HasPhoto).ToList())
    {
        IProfilePhotoContentRequest request = client.Users[member.ObjectID].Photos["96x96"].Content.Request();
        batchResponseIds.Add(member.ObjectID, content.AddBatchRequestStep(request));
        count++;
        currentBatch++;
        if (currentBatch >= MaxBatchCount || count == total) // Max 20 requests per batch
        {
            BatchResponseContent batchResponse = await client.Batch.Request().PostAsync(content);
            foreach (KeyValuePair<string, string> id in batchResponseIds)
            {
                StaffMember temp = staffMembers.Single(c => c.ObjectID == id.Key);
                temp.PhotoBase64 = "data:image/png;base64,";
                using (Stream stream = await batchResponse.GetResponseByIdAsync<Stream>(id.Value))
                {
                    int bytesRead;
                    byte[] buffer = new byte[3072]; // Base64 uses 4 ascii characters to encode 24-bits (3 bytes) of data
                    while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0)
                    {
                        temp.PhotoBase64 += Convert.ToBase64String(buffer, 0, bytesRead);
                    }
                }
            }
            content = new BatchRequestContent();
            batchResponseIds.Clear();
            currentBatch = 0;
        }
    }
}

Stack Trace:

at Newtonsoft.Json.JsonTextReader.ParseComment(Boolean setToken)
at Newtonsoft.Json.JsonTextReader.ParseValue()
at Newtonsoft.Json.JsonTextReader.Read()
at Newtonsoft.Json.JsonReader.ReadForType(JsonContract contract, Boolean hasConverter)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)
at Microsoft.Graph.Serializer.DeserializeObject[T](String inputString)
at Microsoft.Graph.ResponseHandler.<HandleResponse>d__2`1.MoveNext()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
at Microsoft.Graph.BatchResponseContent.<GetResponseByIdAsync>d__9`1.MoveNext()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at MyApp.AppWeb.Controllers.StaffController.<QueryStaffPhotosBatchAsync>d__30.MoveNext() in C:\TFS\MyApp\MyApp.AppWeb\Controllers\StaffController.cs:line 259

Update 09-23-2020

There is an issue logged on github here for msgraph-sdk-dotnet-core to add support for non-json bodies in Batch content (thanks DCCoder).

0 Answers
Related