diff --git a/.github/workflows/validatePullRequest.yml b/.github/workflows/validatePullRequest.yml
index 04c92d6d9..c3f46c5c2 100644
--- a/.github/workflows/validatePullRequest.yml
+++ b/.github/workflows/validatePullRequest.yml
@@ -15,7 +15,7 @@ jobs:
solutionName: Microsoft.Graph.Core.sln
relativePath: ./src/Microsoft.Graph.Core
steps:
- - uses: actions/checkout@v3.0.2
+ - uses: actions/checkout@v3.3.0
- name: Setup .NET
uses: actions/setup-dotnet@v2.1.0
diff --git a/src/Microsoft.Graph.Core/Microsoft.Graph.Core.csproj b/src/Microsoft.Graph.Core/Microsoft.Graph.Core.csproj
index 5660c5a3a..b5bbe5ab5 100644
--- a/src/Microsoft.Graph.Core/Microsoft.Graph.Core.csproj
+++ b/src/Microsoft.Graph.Core/Microsoft.Graph.Core.csproj
@@ -20,10 +20,10 @@
false
35MSSharedLib1024.snk
true
- 3.0.0
+ 3.0.1
-- GA Release supporting Kiota
+- Adds support for enhanced batch requests (https://github.com/microsoftgraph/msgraph-sdk-dotnet-core/issues/612)
true
true
diff --git a/src/Microsoft.Graph.Core/Requests/BatchRequestBuilder.cs b/src/Microsoft.Graph.Core/Requests/BatchRequestBuilder.cs
index 500dfc985..36597450f 100644
--- a/src/Microsoft.Graph.Core/Requests/BatchRequestBuilder.cs
+++ b/src/Microsoft.Graph.Core/Requests/BatchRequestBuilder.cs
@@ -52,6 +52,26 @@ public async Task PostAsync(BatchRequestContent batchReque
return new BatchResponseContent(nativeResponseHandler.Value as HttpResponseMessage);
}
+ ///
+ /// Sends out the using the POST method
+ ///
+ /// The for the request
+ /// to use for cancelling requests
+ ///
+ public async Task PostAsync(BatchRequestContentCollection batchRequestContentCollection, CancellationToken cancellationToken = default)
+ {
+ var collection = new BatchResponseContentCollection();
+
+ var requests = batchRequestContentCollection.GetBatchRequestsForExecution();
+ foreach (var request in requests)
+ {
+ var response = await PostAsync(request, cancellationToken);
+ collection.AddResponse(request.BatchRequestSteps.Keys, response);
+ }
+
+ return collection;
+ }
+
///
/// Create instance to post to batch endpoint
/// The for the request
diff --git a/src/Microsoft.Graph.Core/Requests/Content/BatchRequestContentCollection.cs b/src/Microsoft.Graph.Core/Requests/Content/BatchRequestContentCollection.cs
new file mode 100644
index 000000000..52a4bbcae
--- /dev/null
+++ b/src/Microsoft.Graph.Core/Requests/Content/BatchRequestContentCollection.cs
@@ -0,0 +1,104 @@
+namespace Microsoft.Graph
+{
+ using Microsoft.Kiota.Abstractions;
+ using System;
+ using System.Collections.Generic;
+ using System.Net.Http;
+ using System.Threading.Tasks;
+
+ ///
+ /// A collection of batch requests that are automatically managed.
+ ///
+ public class BatchRequestContentCollection
+ {
+ private readonly IBaseClient baseClient;
+ private readonly List batchRequests;
+ private BatchRequestContent currentRequest;
+ private bool readOnly = false;
+
+ ///
+ /// Constructs a new .
+ ///
+ /// The for making requests
+ public BatchRequestContentCollection(IBaseClient baseClient)
+ {
+ this.baseClient = baseClient;
+ batchRequests = new List();
+ currentRequest = new BatchRequestContent(baseClient);
+ }
+
+ private void ValidateReadOnly()
+ {
+ if (readOnly)
+ {
+ throw new InvalidOperationException("Batch request collection is already executed");
+ }
+ }
+
+ private void SetupCurrentRequest()
+ {
+ ValidateReadOnly();
+ if (currentRequest.BatchRequestSteps.Count >= CoreConstants.BatchRequest.MaxNumberOfRequests)
+ {
+ batchRequests.Add(currentRequest);
+ currentRequest = new BatchRequestContent(baseClient);
+ }
+ }
+
+ ///
+ /// Adds a to batch request content.
+ ///
+ /// A to use to build a to add.
+ /// The requestId of the newly created
+ public string AddBatchRequestStep(HttpRequestMessage httpRequestMessage)
+ {
+ SetupCurrentRequest();
+ return currentRequest.AddBatchRequestStep(httpRequestMessage);
+ }
+
+ ///
+ /// Adds a to batch request content
+ ///
+ /// A to use to build a to add.
+ /// The requestId of the newly created
+ public Task AddBatchRequestStepAsync(RequestInformation requestInformation)
+ {
+ SetupCurrentRequest();
+ return currentRequest.AddBatchRequestStepAsync(requestInformation);
+ }
+
+ ///
+ /// Removes a from batch request content for the specified id.
+ ///
+ /// A unique batch request id to remove.
+ /// True or false based on removal or not removal of a .
+ public bool RemoveBatchRequestStepWithId(string requestId)
+ {
+ ValidateReadOnly();
+ var removed = currentRequest.RemoveBatchRequestStepWithId(requestId);
+ if (!removed && batchRequests.Count > 0)
+ {
+ for (int i = 0; i < batchRequests.Count; i++)
+ {
+ removed = batchRequests[i].RemoveBatchRequestStepWithId(requestId);
+ if (removed)
+ {
+ return true;
+ }
+ }
+ }
+ return removed;
+ }
+
+ internal IEnumerable GetBatchRequestsForExecution()
+ {
+ readOnly = true;
+ if (currentRequest.BatchRequestSteps.Count > 0)
+ {
+ batchRequests.Add(currentRequest);
+ }
+
+ return batchRequests;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.Graph.Core/Requests/Content/BatchResponseContentCollection.cs b/src/Microsoft.Graph.Core/Requests/Content/BatchResponseContentCollection.cs
new file mode 100644
index 000000000..94db00c01
--- /dev/null
+++ b/src/Microsoft.Graph.Core/Requests/Content/BatchResponseContentCollection.cs
@@ -0,0 +1,86 @@
+namespace Microsoft.Graph
+{
+ using Microsoft.Kiota.Abstractions;
+ using Microsoft.Kiota.Abstractions.Serialization;
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Linq;
+ using System.Net.Http;
+ using System.Threading.Tasks;
+
+ ///
+ /// Handles batch request responses.
+ ///
+ public class BatchResponseContentCollection
+ {
+ private readonly List batchResponses;
+
+ internal BatchResponseContentCollection()
+ {
+ batchResponses = new List();
+ }
+
+ internal void AddResponse(IEnumerable keys, BatchResponseContent content)
+ {
+ batchResponses.Add(new KeyedBatchResponseContent(new HashSet(keys), content));
+ }
+
+ private BatchResponseContent GetBatchResponseContaining(string requestId)
+ {
+ return batchResponses.FirstOrDefault(b => b.Keys.Contains(requestId))?.Response;
+ }
+
+ ///
+ /// Gets a batch response as for the specified batch request id.
+ /// The returned MUST be disposed since it implements an .
+ ///
+ /// A batch request id.
+ /// A response object for a batch request.
+ public Task GetResponseByIdAsync(string requestId)
+ {
+ return GetBatchResponseContaining(requestId)?.GetResponseByIdAsync(requestId)
+ ?? Task.FromResult(null);
+ }
+
+ ///
+ /// Gets a batch response as a requested type for the specified batch request id.
+ ///
+ /// A batch request id.
+ /// ResponseHandler to use for the response
+ /// A deserialized object of type T.
+ public Task GetResponseByIdAsync(string requestId, IResponseHandler responseHandler = null) where T : IParsable, new()
+ {
+ return GetBatchResponseContaining(requestId)?.GetResponseByIdAsync(requestId, responseHandler)
+ ?? Task.FromResult(default);
+ }
+
+ ///
+ /// Gets a batch response content as a stream
+ ///
+ /// A batch request id.
+ /// The response stream of the batch response object
+ /// Stream should be dispose once done with.
+ public Task GetResponseStreamByIdAsync(string requestId)
+ {
+ var batch = GetBatchResponseContaining(requestId);
+ if (batch is null)
+ {
+ return Task.FromResult(default);
+ }
+
+ return batch.GetResponseStreamByIdAsync(requestId);
+ }
+
+ ///
+ /// Gets all batch responses .
+ /// All in the dictionary MUST be disposed since they implement .
+ ///
+ /// A Dictionary of id and representing batch responses.
+ /// Not implemented, need help
+ public Task> GetResponsesAsync()
+ {
+ throw new NotImplementedException("GetResponsesAsync() is not available in the BatchCollection");
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.Graph.Core/Requests/Content/KeyedBatchResponseContent.cs b/src/Microsoft.Graph.Core/Requests/Content/KeyedBatchResponseContent.cs
new file mode 100644
index 000000000..0f7daaf01
--- /dev/null
+++ b/src/Microsoft.Graph.Core/Requests/Content/KeyedBatchResponseContent.cs
@@ -0,0 +1,16 @@
+namespace Microsoft.Graph
+{
+ using System.Collections.Generic;
+
+ internal class KeyedBatchResponseContent
+ {
+ internal readonly HashSet Keys;
+ internal readonly BatchResponseContent Response;
+
+ public KeyedBatchResponseContent(HashSet keys, BatchResponseContent response)
+ {
+ Keys = keys;
+ Response = response;
+ }
+ }
+}
\ No newline at end of file