diff --git a/autorest.powershell b/autorest.powershell index 02a628de5bc..31482f7090b 160000 --- a/autorest.powershell +++ b/autorest.powershell @@ -1 +1 @@ -Subproject commit 02a628de5bc5396603c360f1655b8fd0b0e09015 +Subproject commit 31482f7090b0be090024df11f00f1b092ae0f017 diff --git a/src/readme.graph.md b/src/readme.graph.md index d0d4231ba1d..b015bf88c2c 100644 --- a/src/readme.graph.md +++ b/src/readme.graph.md @@ -6,7 +6,6 @@ azure: false powershell: true version: latest -#use: "@autorest/powershell@3.0.509" use: "$(this-folder)../autorest.powershell" export-properties-for-dict: false metadata: @@ -651,7 +650,15 @@ directive: // Fix double = in date parameter. Temp fix for https://github.com/Azure/autorest.powershell/issues/1025. let dateAssignmentRegex = /(date="\n.*)(\+.*"=")(.*\+.*date)/gmi $ = $.replace(dateAssignmentRegex, '$1 $3'); - return $; + + // Allow sending of serialized null properties located in cleanedBody + $ = $.replace(/request\.Content\s*=\s*new\s+global::System\.Net\.Http\.StringContent\(\s*null\s*!=\s*body\s*\?\s*body\.ToJson\(null\)\.ToString\(\)\s*:\s*@"{}",\s*global::System\.Text\.Encoding\.UTF8\);/g,'request.Content = new global::System.Net.Http.StringContent(cleanedBody, global::System.Text.Encoding.UTF8);'); + + $ = $.replace(/request\.Content\s*=\s*new\s+global::System\.Net\.Http\.StringContent\(\s*null\s*!=\s*body\s*\?\s*new\s+Microsoft\.Graph\.PowerShell\.Runtime\.Json\.XNodeArray\(.*?\)\s*:\s*null,\s*global::System\.Text\.Encoding\.UTF8\);/g,'request.Content = new global::System.Net.Http.StringContent(cleanedBody, global::System.Text.Encoding.UTF8);'); + + $ = $.replace(/request\.Content\s*=\s*new\s+global::System\.Net\.Http\.StringContent\(\s*null\s*!=\s*body\s*\?\s*new\s+Microsoft\.Graph\.Beta\.PowerShell\.Runtime\.Json\.XNodeArray\(.*?\)\s*:\s*null,\s*global::System\.Text\.Encoding\.UTF8\);/g,'request.Content = new global::System.Net.Http.StringContent(cleanedBody, global::System.Text.Encoding.UTF8);'); + + return $ } # Fix enums with underscore. diff --git a/tools/Custom/JsonExtensions.cs b/tools/Custom/JsonExtensions.cs index 0c0a69d8889..eedb2ba305a 100644 --- a/tools/Custom/JsonExtensions.cs +++ b/tools/Custom/JsonExtensions.cs @@ -1,62 +1,85 @@ -namespace Microsoft.Graph.PowerShell.JsonUtilities +namespace NamespacePrefixPlaceholder.PowerShell.JsonUtilities { using Newtonsoft.Json.Linq; + using System; using System.Linq; public static class JsonExtensions { /// - /// Removes JSON properties that have a value of "defaultnull" and converts properties with values of "null" to actual JSON null values. + /// Recursively removes properties with the value "defaultnull" from a JSON structure + /// and replaces string values that are "null" with actual null values. + /// This method supports both JObject (JSON objects) and JArray (JSON arrays), + /// ensuring proper cleanup of nested structures. /// - /// The JObject to process and clean. - /// - /// A JSON string representation of the cleaned JObject with "defaultnull" properties removed and "null" values converted to JSON null. - /// + /// The JToken (JObject or JArray) to process. + /// The cleaned JSON string with "defaultnull" values removed and "null" strings converted to null. /// /// JObject json = JObject.Parse(@"{""name"": ""John"", ""email"": ""defaultnull"", ""address"": ""null""}"); /// string cleanedJson = json.RemoveDefaultNullProperties(); /// Console.WriteLine(cleanedJson); /// // Output: { "name": "John", "address": null } /// - public static string RemoveDefaultNullProperties(this JObject jsonObject) + public static string RemoveDefaultNullProperties(this JToken token) { try { - foreach (var property in jsonObject.Properties().ToList()) + if (token is JObject jsonObject) { - if (property.Value.Type == JTokenType.Object) + foreach (var property in jsonObject.Properties().ToList()) { - RemoveDefaultNullProperties((JObject)property.Value); - } - else if (property.Value.Type == JTokenType.Array) - { - foreach (var item in property.Value) + if (property.Value.Type == JTokenType.Object) { - if (item.Type == JTokenType.Object) - { - RemoveDefaultNullProperties((JObject)item); - } + RemoveDefaultNullProperties(property.Value); + } + else if (property.Value.Type == JTokenType.Array) + { + RemoveDefaultNullProperties(property.Value); + } + else if (property.Value.Type == JTokenType.String && property.Value.ToString().Equals("defaultnull",StringComparison.Ordinal)) + { + property.Remove(); + } + else if (property.Value.Type == JTokenType.String && property.Value.ToString().Equals("null",StringComparison.Ordinal)) + { + property.Value = JValue.CreateNull(); } } - else if (property.Value.Type == JTokenType.String && property.Value.ToString() == "defaultnull") - { - property.Remove(); - } - else if (property.Value.Type == JTokenType.String && (property.Value.ToString() == "null")) + } + else if (token is JArray jsonArray) + { + // Process each item in the JArray + for (int i = jsonArray.Count - 1; i >= 0; i--) { - property.Value = JValue.CreateNull(); + var item = jsonArray[i]; + + if (item.Type == JTokenType.Object) + { + RemoveDefaultNullProperties(item); + } + else if (item.Type == JTokenType.String && item.ToString().Equals("defaultnull",StringComparison.Ordinal)) + { + jsonArray.RemoveAt(i); // Remove the "defaultnull" string from the array + } + else if (item.Type == JTokenType.String && item.ToString().Equals("null",StringComparison.Ordinal)) + { + jsonArray[i] = JValue.CreateNull(); // Convert "null" string to actual null + } } } } - catch (System.Exception) + catch (System.Exception ex) { - return jsonObject.ToString(); // Return the original string if parsing fails + Console.WriteLine($"Error cleaning JSON: {ex.Message}"); + return token.ToString(); // Return the original JSON if any error occurs } - return jsonObject.ToString(); + + return token.ToString(); } + public static string ReplaceAndRemoveSlashes(this string body) { return body.Replace("/", "").Replace("\\", "").Replace("rn", "").Replace("\"{", "{").Replace("}\"", "}"); } } -} +} \ No newline at end of file diff --git a/tools/Tests/JsonUtilitiesTest/JsonExtensionsTests.cs b/tools/Tests/JsonUtilitiesTest/JsonExtensionsTests.cs index ed45257e947..0aa03b5b1df 100644 --- a/tools/Tests/JsonUtilitiesTest/JsonExtensionsTests.cs +++ b/tools/Tests/JsonUtilitiesTest/JsonExtensionsTests.cs @@ -2,7 +2,7 @@ using System; using Newtonsoft.Json.Linq; using Xunit; -using Microsoft.Graph.PowerShell.JsonUtilities; +using NamespacePrefixPlaceholder.PowerShell.JsonUtilities; public class JsonExtensionsTests { @@ -45,7 +45,7 @@ public void RemoveDefaultNullProperties_ShouldConvertStringNullToJsonNull() // Assert Assert.Null(result["position"]?.Value()); - Assert.Equal("",result["team"]?.ToString()); + Assert.Equal("", result["team"]?.ToString()); Assert.Equal("Tim", result["displayname"]?.ToString()); Assert.Equal(2000000, result["salary"]?.ToObject()); } @@ -124,5 +124,27 @@ public void RemoveDefaultNullProperties_ShouldNotAlterValidData() Assert.Equal("mayabi@example.com", result["email"]?.ToString()); Assert.Equal(2000000, result["salary"]?.ToObject()); } + + //Add tests for json arrays + [Fact] + public void RemoveDefaultNullProperties_ShouldRemoveDefaultNullValuesInJsonArray() + { + // Arrange + JArray json = JArray.Parse(@"[ + { ""displayname"": ""Tim"", ""email"": ""defaultnull"" } + + ]"); + + // Act + string cleanedJson = json.RemoveDefaultNullProperties(); + JArray result = JArray.Parse(cleanedJson); + + // Assert + Assert.Equal("Tim", result[0]?["displayname"]?.ToString()); + Assert.False(result[0].ToObject().ContainsKey("email")); + + } + + }