Sending Batch Requests To Dynamics 365 Web Api Using C#

Sending Batch Requests to Dynamics 365 Web API Using C#

Executing several CRUD operations in a single network call lowers latency and boosts performance when integrating with the Microsoft Dynamics 365 Web API. Batch requests, which are supported by the OData $batch endpoint, are used for this.

In addition to examining how to manage multipart responses in an organized and reusable manner, this blog will walk through the process of implementing batch requests step-by-step.


Prerequisites

Before we dive into code:


Step-by-Step Breakdown


1. Understand the Structure of a Batch Request


2. Create a Simple Batch Request (Basic Example)

string batchBoundary = "batch_" + Guid.NewGuid(); // unique boundary

var batchContent = new MultipartContent("mixed", batchBoundary);

 

string changeSetId = "changeset_" + Guid.NewGuid(); // unique changeset

var changeSetContent = new MultipartContent("mixed", changeSetId);

 

// Add a PATCH request to the changeset

var updateRequest = new HttpRequestMessage(HttpMethod.Patch, baseUrl + "/api/data/v9.1/accounts(AccountId)");

updateRequest.Content = new StringContent("{ \"name\": \"Updated Account Name\" }", Encoding.UTF8, "application/json");

changeSetContent.Add(updateRequest);

 

// Add changeset to batch

batchContent.Add(changeSetContent);


 3. Send Batch Request Using HttpClient

using (var client = new HttpClient())

{

    client.DefaultRequestHeaders.Add("OData-Version", "4.0");

    client.DefaultRequestHeaders.Add("OData-MaxVersion", "4.0");

    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);

    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

 

    var response = await client.PostAsync(baseUrl + "/api/data/v9.1/$batch", batchContent);

    string responseBody = await response.Content.ReadAsStringAsync();

    Console.WriteLine(responseBody);

}


 Reusable Batch Request Function

For larger systems, a reusable method is useful. Let’s walk through your SendBatchRequestAsync:

4. Construct Reusable Batch Sender

public static async Task<List<JObject>> SendBatchRequestAsync(

    HttpClient httpClient,

    List<HttpContent> listOfRequests,

    ILogger log,

    int count = 0,

    string methodType = null)

Key Responsibilities:


 5. Handle Nested Multipart Response

Responses from batch are in multipart/mixed format. To process them:

MultipartMemoryStreamProvider body = await response.Content.ReadAsMultipartAsync();

List<HttpResponseMessage> responses = await ReadHttpContents(body, log);


 6. Helper Method to Read HTTP Parts

 

public static async Task<List<HttpResponseMessage>> ReadHttpContents(MultipartMemoryStreamProvider body, ILogger log)

 Responsibilities:


 7. Deserialize Plain HTTP Content

If a content part isn’t a full HTTP response, you can still deserialize the stream manually into an HttpResponseMessage.

HttpResponseMessage responseMessage = DeserializeToResponse(await c.ReadAsStreamAsync(), log);

You can implement DeserializeToResponse using custom logic or libraries like HttpClientMock/manual parsing.


 Example Use Case

You may need to:

This method helps you optimize by reducing the number of round trips to the server.


Best Practices


 Summary

In this guide, you learned:


 Ready-to-Use Template

You can package this logic into a utility class like DynamicsBatchHelper, making it reusable across microservices or Azure Functions.

 

how-to-build-batch-request-dynamics-365

Discussion


could you please elaborate access token, how it works.

By: Varun Chalamalasetty | varun@gmail.com | July 4, 2025, 6:34 a.m.

No answers yet.