Batching in Microsoft Graph

606 views Asked by At

I added the following code to add users to AAD group in batches in C#:

        public IEnumerable<BatchRequestContent> FindBatches(IEnumerable<AzureADUser> users, AzureADGroup targetGroup)
        {
            var batches = GetBatchRequest(users, targetGroup);
            await AddUsersToGroup(batches);
        }        

        private IEnumerable<BatchRequestContent> GetBatchRequest(IEnumerable<AzureADUser> users, AzureADGroup targetGroup)
        {
            var batches = new List<BatchRequestContent>();
            int maxNoBatchItems = 20;

            var batchRequestContent = new BatchRequestContent();
            int requestId = 1;

            foreach (var user in users)
            {
                JObject body = new JObject
                {
                    ["[email protected]"] = $"https://graph.microsoft.com/v1.0/users/{user.ObjectId}"
                };

                var httpRequestMessage = new HttpRequestMessage(HttpMethod.Patch, $"https://graph.microsoft.com/v1.0/groups/{targetGroup.ObjectId}");
                httpRequestMessage.Content = new StringContent(body.ToString(), Encoding.UTF8, "application/json");

                batchRequestContent.AddBatchRequestStep(new BatchRequestStep(requestId.ToString(), httpRequestMessage));

                if (batchRequestContent.BatchRequestSteps.Count() % maxNoBatchItems == 0)
                {
                    batches.Add(batchRequestContent);
                    batchRequestContent = new BatchRequestContent();
                }

                requestId++;
            }

            if (batchRequestContent.BatchRequestSteps.Count < maxNoBatchItems)
            {
                batches.Add(batchRequestContent);
            }

            return batches;
        }

        public async Task AddUsersToGroup(IEnumerable<BatchRequestContent> batches)
        {
            try
            {
                foreach (var batchRequestContent in batches)
                {
                    var response = await _graphServiceClient
                        .Batch
                        .Request()
                        .WithMaxRetry(10)
                        .PostAsync(batchRequestContent);

                    var responses = await response.GetResponsesAsync();

                    foreach (string key in responses.Keys)
                    {
                      HttpResponseMessage httpResponse = await response.GetResponseByIdAsync(key);
                      var responseContent = await httpResponse.Content.ReadAsStringAsync();                      
                      Console.WriteLine($"Response code: {responses[key].StatusCode}-{responses[key].ReasonPhrase}");
                }
                }
            }
            catch (Exception ex)
            {                
            }
        }

When I run this code, I see 'Bad Request' from the line:

var responses = await response.GetResponsesAsync();

enter image description here

Response status code does not indicate success: 400 (Bad Request).

enter image description here

On putting a breakpoint on Line:

 var responseContent = await httpResponse.Content.ReadAsStringAsync();       

I see the following error:

{ "error": { "code": "Request_BadRequest", "message": "The resource set reference navigation property 'members' has a property annotation 'odata.bind' with a string value. Resource set reference navigation properties can only have a property annotation 'odata.bind' with an array value."} }

What am I missing?

0

There are 0 answers