diff --git a/src/3.0-JsonMergePatch.SystemText/Builders/PatchBuilder.cs b/src/3.0-JsonMergePatch.SystemText/Builders/PatchBuilder.cs index e4f55b3..0578eaa 100644 --- a/src/3.0-JsonMergePatch.SystemText/Builders/PatchBuilder.cs +++ b/src/3.0-JsonMergePatch.SystemText/Builders/PatchBuilder.cs @@ -1,5 +1,6 @@ using Morcatko.AspNetCore.JsonMergePatch.Internal; using System; +using System.Linq; using System.Reflection; using System.Text.Json; @@ -14,25 +15,23 @@ private static object ToObject(this JsonElement jsonElement) case JsonValueKind.Null: return null; case JsonValueKind.String: return jsonElement.GetString(); case JsonValueKind.Number: return jsonElement.GetGenericNumber(); + case JsonValueKind.Array: return jsonElement.EnumerateArray().Select(j => j.ToObject()).ToArray(); case JsonValueKind.True: return true; case JsonValueKind.False: return false; case JsonValueKind.Undefined: case JsonValueKind.Object: - case JsonValueKind.Array: default: throw new NotSupportedException($"Unsupported ValueKind - {jsonElement.ValueKind}"); } } - private static object GetGenericNumber (this JsonElement jsonElement) - { - - // Attempt to parse the JSON Element as an Int32 first - if (jsonElement.TryGetInt32(out int int32)) return int32; - - // Failing that, parse it as a Decimal instead - return jsonElement.GetDecimal(); - + private static object GetGenericNumber(this JsonElement jsonElement) + { + // Attempt to parse the JSON Element as an Int32 first + if (jsonElement.TryGetInt32(out int int32)) return int32; + + // Failing that, parse it as a Decimal instead + return jsonElement.GetDecimal(); } private static bool IsValue(this JsonValueKind valueKind) diff --git a/src/3.0-JsonMergePatch.Tests/Integration/MvcTest.cs b/src/3.0-JsonMergePatch.Tests/Integration/MvcTest.cs index a0a5b0b..7de21dd 100644 --- a/src/3.0-JsonMergePatch.Tests/Integration/MvcTest.cs +++ b/src/3.0-JsonMergePatch.Tests/Integration/MvcTest.cs @@ -123,7 +123,8 @@ await p.MergePatchAsync(null, new[] [MemberData(nameof(GetCombinations))] public async Task NullableDecimalFloatingPoint(bool core, bool newtonsoft) { - using (var p = new TestHelper(core, newtonsoft)) { + using (var p = new TestHelper(core, newtonsoft)) + { await p.PostAsync("0", p.GetTestModel()); await p.MergePatchAsync(null, new[] @@ -133,11 +134,31 @@ await p.MergePatchAsync(null, new[] var patchedModel = await p.GetAsync("0"); var expected = p.GetTestModel(); - expected.NullableDecimal = (decimal?) 7.5; + expected.NullableDecimal = (decimal?)7.5; Assert.Equal(expected, patchedModel); } } + [Theory] + [MemberData(nameof(GetCombinations))] + public async Task Arrays(bool core, bool newtonsoft) + { + using (var p = new TestHelper(core, newtonsoft)) + { + await p.PostAsync("0", p.GetTestModel()); + + await p.MergePatchAsync(null, new[] + { + new { id = 0, ArrayOfFloats = new [] { 7, 3.5f }} + }); + + var patchedModel = await p.GetAsync("0"); + var expected = p.GetTestModel(); + expected.ArrayOfFloats = new [] { 7, 3.5f }; + Assert.Equal(expected, patchedModel); + } + } + [Theory(Skip = "Does not work")] [MemberData(nameof(GetCombinations))] public async Task MissingRequiredProperty(bool core, bool newtonsoft) @@ -152,8 +173,8 @@ public async Task MissingRequiredProperty(bool core, bool newtonsoft) expected.Integer = 8; Assert.Equal(expected, patchedModel); } - } - + } + #region ValueEnum [Theory(Skip = "Enums do not work - https://github.com/aspnet/Home/issues/2423")] [MemberData(nameof(GetCombinations))] diff --git a/src/3.0-JsonMergePatch.Tests/TestModel.cs b/src/3.0-JsonMergePatch.Tests/TestModel.cs index 10c9f18..d3f6b7a 100644 --- a/src/3.0-JsonMergePatch.Tests/TestModel.cs +++ b/src/3.0-JsonMergePatch.Tests/TestModel.cs @@ -29,6 +29,8 @@ public class TestModelBase : IEquatable, IEquatable SubModels { get; set; } = new Dictionary(); public bool Equals(TestModelBase other) @@ -43,7 +45,8 @@ public bool Equals(TestModelBase other) && this.ValueEnum == other.ValueEnum && this.NullableDecimal == other.NullableDecimal && this.Date == other.Date - && this.Date.GetValueOrDefault().Offset == other.Date.GetValueOrDefault().Offset + && this.Date.GetValueOrDefault().Offset == other.Date.GetValueOrDefault().Offset + && Enumerable.SequenceEqual(this.ArrayOfFloats, other.ArrayOfFloats) && Enumerable.SequenceEqual(this.SubModels?.Keys, other.SubModels?.Keys) && Enumerable.SequenceEqual(this.SubModels?.Values, other.SubModels?.Values) && ((this.SubModel == other.SubModel) diff --git a/src/6.0-JsonMergePatch.SystemText/Builders/PatchBuilder.cs b/src/6.0-JsonMergePatch.SystemText/Builders/PatchBuilder.cs index ad777ca..8162120 100644 --- a/src/6.0-JsonMergePatch.SystemText/Builders/PatchBuilder.cs +++ b/src/6.0-JsonMergePatch.SystemText/Builders/PatchBuilder.cs @@ -1,5 +1,6 @@ using Morcatko.AspNetCore.JsonMergePatch.Internal; using System; +using System.Linq; using System.Reflection; using System.Text.Json; @@ -41,25 +42,25 @@ private static object ToObject(this JsonElement jsonElement) { case JsonValueKind.Null: return null; case JsonValueKind.String: return jsonElement.GetString(); - case JsonValueKind.Number: return jsonElement.GetGenericNumber(); + case JsonValueKind.Number: return jsonElement.GetGenericNumber(); + case JsonValueKind.Array: return jsonElement.EnumerateArray().Select(j => j.ToObject()).ToArray(); case JsonValueKind.True: return true; case JsonValueKind.False: return false; case JsonValueKind.Undefined: case JsonValueKind.Object: - case JsonValueKind.Array: default: throw new NotSupportedException($"Unsupported ValueKind - {jsonElement.ValueKind}"); } } - private static object GetGenericNumber (this JsonElement jsonElement) - { - - // Attempt to parse the JSON Element as an Int32 first - if (jsonElement.TryGetInt32(out int int32)) return int32; - - // Failing that, parse it as a Decimal instead - return jsonElement.GetDecimal(); + private static object GetGenericNumber(this JsonElement jsonElement) + { + + // Attempt to parse the JSON Element as an Int32 first + if (jsonElement.TryGetInt32(out int int32)) return int32; + + // Failing that, parse it as a Decimal instead + return jsonElement.GetDecimal(); } diff --git a/src/6.0-JsonMergePatch.Tests/Integration/MvcTest.cs b/src/6.0-JsonMergePatch.Tests/Integration/MvcTest.cs index 9b1a19c..f085363 100644 --- a/src/6.0-JsonMergePatch.Tests/Integration/MvcTest.cs +++ b/src/6.0-JsonMergePatch.Tests/Integration/MvcTest.cs @@ -123,7 +123,8 @@ await p.MergePatchAsync(null, new[] [MemberData(nameof(GetCombinations))] public async Task NullableDecimalFloatingPoint(bool core, bool newtonsoft) { - using (var p = new TestHelper(core, newtonsoft)) { + using (var p = new TestHelper(core, newtonsoft)) + { await p.PostAsync("0", p.GetTestModel()); await p.PostAsync("1", p.GetTestModel()); @@ -135,11 +136,31 @@ await p.MergePatchAsync(null, new[] var patchedModel = await p.GetAsync("0"); var expected = p.GetTestModel(); - expected.NullableDecimal = (decimal?) 7.5; + expected.NullableDecimal = (decimal?)7.5; Assert.Equal(expected, patchedModel); } } + [Theory] + [MemberData(nameof(GetCombinations))] + public async Task Arrays(bool core, bool newtonsoft) + { + using (var p = new TestHelper(core, newtonsoft)) + { + await p.PostAsync("0", p.GetTestModel()); + + await p.MergePatchAsync(null, new[] + { + new { id = 0, ArrayOfFloats = new [] { 7, 3.5f }} + }); + + var patchedModel = await p.GetAsync("0"); + var expected = p.GetTestModel(); + expected.ArrayOfFloats = new[] { 7, 3.5f }; + Assert.Equal(expected, patchedModel); + } + } + [Theory(Skip = "Does not work")] [MemberData(nameof(GetCombinations))] public async Task MissingRequiredProperty(bool core, bool newtonsoft) @@ -154,8 +175,8 @@ public async Task MissingRequiredProperty(bool core, bool newtonsoft) expected.Integer = 8; Assert.Equal(expected, patchedModel); } - } - + } + #region ValueEnum [Theory(Skip = "Enums do not work - https://github.com/aspnet/Home/issues/2423")] [MemberData(nameof(GetCombinations))] diff --git a/src/6.0-JsonMergePatch.Tests/TestModel.cs b/src/6.0-JsonMergePatch.Tests/TestModel.cs index 10c9f18..496dd0e 100644 --- a/src/6.0-JsonMergePatch.Tests/TestModel.cs +++ b/src/6.0-JsonMergePatch.Tests/TestModel.cs @@ -29,6 +29,8 @@ public class TestModelBase : IEquatable, IEquatable SubModels { get; set; } = new Dictionary(); public bool Equals(TestModelBase other) @@ -44,6 +46,7 @@ public bool Equals(TestModelBase other) && this.NullableDecimal == other.NullableDecimal && this.Date == other.Date && this.Date.GetValueOrDefault().Offset == other.Date.GetValueOrDefault().Offset + && Enumerable.SequenceEqual(this.ArrayOfFloats, other.ArrayOfFloats) && Enumerable.SequenceEqual(this.SubModels?.Keys, other.SubModels?.Keys) && Enumerable.SequenceEqual(this.SubModels?.Values, other.SubModels?.Values) && ((this.SubModel == other.SubModel)