diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializer.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializer.cs index 6f433ce918..7f72f0de71 100644 --- a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializer.cs +++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializer.cs @@ -40,21 +40,10 @@ public class AbpSystemTextJsonSerializer : IJsonSerializer, ITransientDependency camelCase, indented, Options.JsonSerializerOptions - }, _ => + }, _ => new JsonSerializerOptions(Options.JsonSerializerOptions) { - var settings = new JsonSerializerOptions(Options.JsonSerializerOptions); - - if (camelCase) - { - settings.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; - } - - if (indented) - { - settings.WriteIndented = true; - } - - return settings; + PropertyNamingPolicy = camelCase ? JsonNamingPolicy.CamelCase : null, + WriteIndented = indented }); } } diff --git a/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpJsonTestBase.cs b/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpJsonTestBase.cs index ebae706aca..e442ce48ad 100644 --- a/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpJsonTestBase.cs +++ b/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpJsonTestBase.cs @@ -1,4 +1,9 @@ -using Volo.Abp.Testing; +using System; +using System.Collections.Concurrent; +using System.Reflection; +using Newtonsoft.Json; +using Volo.Abp.Json.Newtonsoft; +using Volo.Abp.Testing; namespace Volo.Abp.Json; @@ -12,6 +17,16 @@ public abstract class AbpJsonSystemTextJsonTestBase : AbpIntegratedTest { + protected AbpJsonNewtonsoftJsonTestBase() + { + var cache = typeof(AbpNewtonsoftJsonSerializer).GetField("JsonSerializerOptionsCache", BindingFlags.NonPublic | BindingFlags.Static); + if (cache != null) + { + var cacheValue = cache.GetValue(null)?.As>(); + cacheValue?.Clear(); + } + } + protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) { options.UseAutofac(); diff --git a/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpNewtonsoftSerializerProviderTests.cs b/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpNewtonsoftSerializerProviderTests.cs new file mode 100644 index 0000000000..9dc0c0afd3 --- /dev/null +++ b/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpNewtonsoftSerializerProviderTests.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using Shouldly; +using Xunit; + +namespace Volo.Abp.Json; + +[Collection("AbpJsonNewtonsoftJsonTest")] +public class AbpNewtonsoftSerializerProviderTests : AbpJsonNewtonsoftJsonTestBase +{ + protected IJsonSerializer JsonSerializer; + + public AbpNewtonsoftSerializerProviderTests() + { + JsonSerializer = GetRequiredService(); + } + + public class File + { + public string FileName { get; set; } + + public Dictionary ExtraProperties { get; set; } + } + + [Fact] + public void Serialize_Deserialize_Test() + { + var defaultIndent = " "; // Default indent is 2 spaces + var newLine = Environment.NewLine; + var file = new File() + { + FileName = "abp", + ExtraProperties = new Dictionary() + { + { "One", 1 }, + { "Two", 2 } + } + }; + + var json = JsonSerializer.Serialize(file, camelCase: true); + json.ShouldBe("{\"fileName\":\"abp\",\"extraProperties\":{\"One\":1,\"Two\":2}}"); + + json = JsonSerializer.Serialize(file, camelCase: true, indented: true); + json.ShouldBe($"{{{newLine}{defaultIndent}\"fileName\": \"abp\",{newLine}{defaultIndent}\"extraProperties\": {{{newLine}{defaultIndent}{defaultIndent}\"One\": 1,{newLine}{defaultIndent}{defaultIndent}\"Two\": 2{newLine}{defaultIndent}}}{newLine}}}"); + + json = JsonSerializer.Serialize(file, camelCase: false); + json.ShouldBe("{\"FileName\":\"abp\",\"ExtraProperties\":{\"One\":1,\"Two\":2}}"); + + json = JsonSerializer.Serialize(file, camelCase: false, indented: true); + json.ShouldBe($"{{{newLine}{defaultIndent}\"FileName\": \"abp\",{newLine}{defaultIndent}\"ExtraProperties\": {{{newLine}{defaultIndent}{defaultIndent}\"One\": 1,{newLine}{defaultIndent}{defaultIndent}\"Two\": 2{newLine}{defaultIndent}}}{newLine}}}"); + } +} diff --git a/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpSystemTextJsonSerializerProvider_Tests.cs b/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpSystemTextJsonSerializerProvider_Tests.cs index e32df85d7f..49b321d46d 100644 --- a/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpSystemTextJsonSerializerProvider_Tests.cs +++ b/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpSystemTextJsonSerializerProvider_Tests.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Text.Json; using Microsoft.Extensions.DependencyInjection; using Shouldly; using Volo.Abp.Data; @@ -11,11 +13,11 @@ namespace Volo.Abp.Json; public abstract class AbpSystemTextJsonSerializerProviderTestBase : AbpJsonSystemTextJsonTestBase { - protected AbpSystemTextJsonSerializer JsonSerializer; + protected IJsonSerializer JsonSerializer; public AbpSystemTextJsonSerializerProviderTestBase() { - JsonSerializer = GetRequiredService(); + JsonSerializer = GetRequiredService(); } public class TestExtensibleObjectClass : ExtensibleObject @@ -23,6 +25,13 @@ public abstract class AbpSystemTextJsonSerializerProviderTestBase : AbpJsonSyste public string Name { get; set; } } + public class File + { + public string FileName { get; set; } + + public Dictionary ExtraProperties { get; set; } + } + public class FileWithBoolean { public string Name { get; set; } @@ -74,6 +83,34 @@ public abstract class AbpSystemTextJsonSerializerProviderTestBase : AbpJsonSyste public class AbpSystemTextJsonSerializerProviderTests : AbpSystemTextJsonSerializerProviderTestBase { + [Fact] + public void Serialize_Deserialize_Test() + { + var defaultIndent = " "; // Default indent is 2 spaces + var newLine = Environment.NewLine; + var file = new File() + { + FileName = "abp", + ExtraProperties = new Dictionary() + { + { "One", 1 }, + { "Two", 2 } + } + }; + + var json = JsonSerializer.Serialize(file, camelCase: true); + json.ShouldBe("{\"fileName\":\"abp\",\"extraProperties\":{\"One\":1,\"Two\":2}}"); + + json = JsonSerializer.Serialize(file, camelCase: true, indented: true); + json.ShouldBe($"{{{newLine}{defaultIndent}\"fileName\": \"abp\",{newLine}{defaultIndent}\"extraProperties\": {{{newLine}{defaultIndent}{defaultIndent}\"One\": 1,{newLine}{defaultIndent}{defaultIndent}\"Two\": 2{newLine}{defaultIndent}}}{newLine}}}"); + + json = JsonSerializer.Serialize(file, camelCase: false); + json.ShouldBe("{\"FileName\":\"abp\",\"ExtraProperties\":{\"One\":1,\"Two\":2}}"); + + json = JsonSerializer.Serialize(file, camelCase: false, indented: true); + json.ShouldBe($"{{{newLine}{defaultIndent}\"FileName\": \"abp\",{newLine}{defaultIndent}\"ExtraProperties\": {{{newLine}{defaultIndent}{defaultIndent}\"One\": 1,{newLine}{defaultIndent}{defaultIndent}\"Two\": 2{newLine}{defaultIndent}}}{newLine}}}"); + } + [Fact] public void Serialize_Deserialize_With_Boolean() { @@ -223,6 +260,8 @@ public class AbpSystemTextJsonSerializerProviderDateTimeFormatTests : AbpSystemT options.InputDateTimeFormats.Add("yyyy*MM*dd"); options.OutputDateTimeFormat = "yyyy*MM*dd HH*mm*ss"; }); + + base.AfterAddApplication(services); } [Fact] @@ -289,6 +328,8 @@ public class AbpSystemTextJsonSerializerProviderDatetimeKindUtcTests : AbpSystem { Kind = DateTimeKind.Utc; services.Configure(x => x.Kind = Kind); + + base.AfterAddApplication(services); } } @@ -298,6 +339,8 @@ public class AbpSystemTextJsonSerializerProviderDatetimeKindLocalTests : AbpSyst { Kind = DateTimeKind.Local; services.Configure(x => x.Kind = Kind); + + base.AfterAddApplication(services); } } diff --git a/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/InputAndOutputDateTimeFormat_Tests.cs b/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/InputAndOutputDateTimeFormat_Tests.cs index cf6356477d..189a82cae0 100644 --- a/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/InputAndOutputDateTimeFormat_Tests.cs +++ b/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/InputAndOutputDateTimeFormat_Tests.cs @@ -31,6 +31,8 @@ public class InputAndOutputDateTimeFormatSystemTextJsonTests : AbpJsonSystemText { options.Kind = DateTimeKind.Utc; }); + + base.AfterAddApplication(services); } [Fact] @@ -59,6 +61,7 @@ public class InputAndOutputDateTimeFormatSystemTextJsonTests : AbpJsonSystemText } } +[Collection("AbpJsonNewtonsoftJsonTest")] public class InputAndOutputDateTimeFormatNewtonsoftTests : AbpJsonNewtonsoftJsonTestBase { private readonly IJsonSerializer _jsonSerializer; @@ -83,6 +86,8 @@ public class InputAndOutputDateTimeFormatNewtonsoftTests : AbpJsonNewtonsoftJson { options.Kind = DateTimeKind.Utc; }); + + base.AfterAddApplication(services); } [Fact]