From 2673679fd01b5e01aeab66cc6eca2c9ff5d790f5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 2 Nov 2025 17:18:59 +0000 Subject: [PATCH 1/3] Initial plan From 5e90d0f4622dac06111ed68ad421d2e88f53f625 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 2 Nov 2025 17:24:38 +0000 Subject: [PATCH 2/3] Change customHeaders parameter type from Dictionary> to Dictionary Co-authored-by: vignaesh01 <13076411+vignaesh01@users.noreply.github.com> --- .../Helpers/DataManagementHelper.cs | 15 +++++++++++ .../Tools/DataManagementTools.cs | 25 +++++++++++-------- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/DataverseDevToolsMcpServer/Helpers/DataManagementHelper.cs b/DataverseDevToolsMcpServer/Helpers/DataManagementHelper.cs index 096b8ac..16d3c77 100644 --- a/DataverseDevToolsMcpServer/Helpers/DataManagementHelper.cs +++ b/DataverseDevToolsMcpServer/Helpers/DataManagementHelper.cs @@ -145,6 +145,21 @@ public static string CleanRequestUrl(string requestUrl) } return requestUrl; } + + public static Dictionary>? ConvertCustomHeaders(Dictionary? customHeaders) + { + if (customHeaders == null) + { + return null; + } + + var convertedHeaders = new Dictionary>(); + foreach (var header in customHeaders) + { + convertedHeaders[header.Key] = new List { header.Value }; + } + return convertedHeaders; + } } diff --git a/DataverseDevToolsMcpServer/Tools/DataManagementTools.cs b/DataverseDevToolsMcpServer/Tools/DataManagementTools.cs index 63aca1a..6ce4832 100644 --- a/DataverseDevToolsMcpServer/Tools/DataManagementTools.cs +++ b/DataverseDevToolsMcpServer/Tools/DataManagementTools.cs @@ -111,7 +111,7 @@ public async Task ExecuteWebApi( [Description(@"Web API request URL (relative to the service root URL).Request url should not contain /api/data/v9.*/. The path and query parameters that you wish to pass onto the Web API")] string requestUrl, [Description("Request body in JSON format (for POST and PATCH requests)")] string requestBody = null, - [Description("Additional headers")] Dictionary> customHeaders = null, + [Description("Additional headers")] Dictionary customHeaders = null, [Description("Content Type")] string contentType = "application/json" ) { @@ -123,7 +123,8 @@ public async Task ExecuteWebApi( { var method = new System.Net.Http.HttpMethod(httpMethod.ToUpper()); requestUrl =DataManagementHelper.CleanRequestUrl(requestUrl); - var response = await serviceClient.ExecuteWebRequestAsync(method, requestUrl, requestBody, customHeaders, contentType); + var convertedHeaders = DataManagementHelper.ConvertCustomHeaders(customHeaders); + var response = await serviceClient.ExecuteWebRequestAsync(method, requestUrl, requestBody, convertedHeaders, contentType); if (response.IsSuccessStatusCode) { //append response headers to result @@ -163,7 +164,7 @@ public async Task CreateRecord( [Description(@"Record data in JSON format. Prepare the payload based on field/column type. For lookup columns,find the field/column schema name using entity metadata and use the <>@odata.bind in payload")] string recordDataJson, - [Description("Additional headers")] Dictionary> customHeaders = null, + [Description("Additional headers")] Dictionary customHeaders = null, [Description("Content Type")] string contentType = "application/json" ) { @@ -174,7 +175,8 @@ Prepare the payload based on field/column type. try { //var requestUrl = $"/api/data/v9.2/{entitySetName}"; - var response = await serviceClient.ExecuteWebRequestAsync(new System.Net.Http.HttpMethod("POST"), entitySetName, recordDataJson, customHeaders, contentType); + var convertedHeaders = DataManagementHelper.ConvertCustomHeaders(customHeaders); + var response = await serviceClient.ExecuteWebRequestAsync(new System.Net.Http.HttpMethod("POST"), entitySetName, recordDataJson, convertedHeaders, contentType); if (response.IsSuccessStatusCode) { if (response.Headers.Contains("OData-EntityId")) @@ -211,7 +213,7 @@ public async Task UpdateRecord( [Description(@"Record data in JSON format. Prepare the payload based on field/column type. For lookup columns,find the field/column schema name using entity metadata and use the <>@odata.bind in payload")] string recordDataJson, - [Description("Additional headers")] Dictionary> customHeaders = null, + [Description("Additional headers")] Dictionary customHeaders = null, [Description("Content Type")] string contentType = "application/json" ) { @@ -224,7 +226,8 @@ Prepare the payload based on field/column type. try { //var requestUrl = $"/api/data/v9.2/{entitySetName}"; - var response = await serviceClient.ExecuteWebRequestAsync(new System.Net.Http.HttpMethod("PATCH"), entitySetName, recordDataJson, customHeaders, contentType); + var convertedHeaders = DataManagementHelper.ConvertCustomHeaders(customHeaders); + var response = await serviceClient.ExecuteWebRequestAsync(new System.Net.Http.HttpMethod("PATCH"), entitySetName, recordDataJson, convertedHeaders, contentType); if (response.IsSuccessStatusCode) { @@ -260,7 +263,7 @@ public async Task UpsertRecord( [Description(@"Record data in JSON format. Prepare the payload based on field/column type. For lookup columns,find the field/column schema name using entity metadata and use the <>@odata.bind in payload")] string recordDataJson, - [Description("Additional headers")] Dictionary> customHeaders = null, + [Description("Additional headers")] Dictionary customHeaders = null, [Description("Content Type")] string contentType = "application/json" ) { @@ -274,7 +277,8 @@ Prepare the payload based on field/column type. try { //var requestUrl = $"/api/data/v9.2/{entitySetName}"; - var response = await serviceClient.ExecuteWebRequestAsync(new System.Net.Http.HttpMethod("PATCH"), entitySetName, recordDataJson, customHeaders, contentType); + var convertedHeaders = DataManagementHelper.ConvertCustomHeaders(customHeaders); + var response = await serviceClient.ExecuteWebRequestAsync(new System.Net.Http.HttpMethod("PATCH"), entitySetName, recordDataJson, convertedHeaders, contentType); if (response.IsSuccessStatusCode) { @@ -299,7 +303,7 @@ public async Task DeleteRecord( ServiceClient serviceClient, [Description("Entity Set Name from Entity metadata")] string entitySetName, [Description("Record Id")] string recordId, - [Description("Additional headers")] Dictionary> customHeaders = null, + [Description("Additional headers")] Dictionary customHeaders = null, [Description("Content Type")] string contentType = "application/json" ) { @@ -311,7 +315,8 @@ public async Task DeleteRecord( try { //var requestUrl = $"/api/data/v9.2/{entitySetName}"; - var response = await serviceClient.ExecuteWebRequestAsync(new System.Net.Http.HttpMethod("DELETE"), entitySetName, null, customHeaders, contentType); + var convertedHeaders = DataManagementHelper.ConvertCustomHeaders(customHeaders); + var response = await serviceClient.ExecuteWebRequestAsync(new System.Net.Http.HttpMethod("DELETE"), entitySetName, null, convertedHeaders, contentType); if (response.IsSuccessStatusCode) { result = $"Record deleted successfully. Entity ID: {recordId}"; From c6057fa25db38a4b73562998dc271088abf88423 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 2 Nov 2025 17:25:30 +0000 Subject: [PATCH 3/3] Refactor ConvertCustomHeaders to use LINQ for better efficiency Co-authored-by: vignaesh01 <13076411+vignaesh01@users.noreply.github.com> --- .../Helpers/DataManagementHelper.cs | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/DataverseDevToolsMcpServer/Helpers/DataManagementHelper.cs b/DataverseDevToolsMcpServer/Helpers/DataManagementHelper.cs index 16d3c77..da66c76 100644 --- a/DataverseDevToolsMcpServer/Helpers/DataManagementHelper.cs +++ b/DataverseDevToolsMcpServer/Helpers/DataManagementHelper.cs @@ -148,17 +148,7 @@ public static string CleanRequestUrl(string requestUrl) public static Dictionary>? ConvertCustomHeaders(Dictionary? customHeaders) { - if (customHeaders == null) - { - return null; - } - - var convertedHeaders = new Dictionary>(); - foreach (var header in customHeaders) - { - convertedHeaders[header.Key] = new List { header.Value }; - } - return convertedHeaders; + return customHeaders?.ToDictionary(h => h.Key, h => new List { h.Value }); } }