diff --git a/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpHasExtraPropertiesJsonConverter.cs b/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpHasExtraPropertiesJsonConverter.cs index 06cf0ae040..fa1a4f4fcf 100644 --- a/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpHasExtraPropertiesJsonConverter.cs +++ b/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpHasExtraPropertiesJsonConverter.cs @@ -11,11 +11,23 @@ namespace Volo.Abp.Json.SystemTextJson.JsonConverters { public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - var newOptions = JsonSerializerOptionsHelper.Create(options, x => - x == this || - x.GetType() == typeof(AbpHasExtraPropertiesJsonConverterFactory)); + var newOptions = JsonSerializerOptionsHelper.Create(options, x => x == this); + + var converterFactory = newOptions.Converters.FirstOrDefault(x => x is AbpHasExtraPropertiesJsonConverterFactory).As(); + var newConverterFactory = new AbpHasExtraPropertiesJsonConverterFactory(); + if (converterFactory != null) + { + newOptions.Converters.Remove(converterFactory); + newConverterFactory.AddExcludeTypes(converterFactory.GetExcludeTypes().ToArray()); + } + else + { + newConverterFactory.AddExcludeTypes(typeToConvert); + } + + newConverterFactory.AddExcludeTypes(typeToConvert); + newOptions.Converters.Add(newConverterFactory); - newOptions.Converters.Add(new AbpHasExtraPropertiesJsonConverterFactory(typeToConvert)); var rootElement = JsonDocument.ParseValue(ref reader).RootElement; if (rootElement.ValueKind == JsonValueKind.Object) { diff --git a/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpHasExtraPropertiesJsonConverterFactory.cs b/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpHasExtraPropertiesJsonConverterFactory.cs index 0bc9cef11e..dff25e00df 100644 --- a/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpHasExtraPropertiesJsonConverterFactory.cs +++ b/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpHasExtraPropertiesJsonConverterFactory.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Collections.Immutable; using System.Reflection; using System.Text.Json; using System.Text.Json.Serialization; @@ -12,16 +13,22 @@ namespace Volo.Abp.Json.SystemTextJson.JsonConverters { private static readonly ConcurrentDictionary CachedTypes = new ConcurrentDictionary(); - private static readonly List ExcludeTypes = new List(); + private readonly List _excludeTypes = new List(); - public AbpHasExtraPropertiesJsonConverterFactory(params Type[] excludeTypes) + public virtual AbpHasExtraPropertiesJsonConverterFactory AddExcludeTypes(params Type[] excludeTypes) { - ExcludeTypes.AddIfNotContains(excludeTypes); + _excludeTypes.AddIfNotContains(excludeTypes); + return this; + } + + public virtual IReadOnlyList GetExcludeTypes() + { + return _excludeTypes.ToImmutableList(); } public override bool CanConvert(Type typeToConvert) { - if (ExcludeTypes.Contains(typeToConvert)) + if (_excludeTypes.Contains(typeToConvert)) { return false; } diff --git a/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpHasExtraPropertiesJsonConverter_Tests.cs b/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpHasExtraPropertiesJsonConverter_Tests.cs index b80380086d..c11e8f3cec 100644 --- a/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpHasExtraPropertiesJsonConverter_Tests.cs +++ b/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpHasExtraPropertiesJsonConverter_Tests.cs @@ -43,6 +43,22 @@ namespace Volo.Abp.Json fooDto.BarDtos.Count.ShouldBe(1); fooDto.BarDtos.First().Name.ShouldBe("bar-dto"); fooDto.BarDtos.First().GetProperty("bar").ShouldBe("bar-value"); + + fooDto.Name = "new-foo-dto"; + fooDto.SetProperty("foo", "new-foo-value"); + fooDto.BarDtos.First().Name = "new-bar-dto"; + fooDto.BarDtos.First().SetProperty("bar", "new-bar-value"); + + json = _jsonSerializer.Serialize(fooDto); + + fooDto = _jsonSerializer.Deserialize(json); + fooDto.ShouldNotBeNull(); + fooDto.Name.ShouldBe("new-foo-dto"); + fooDto.GetProperty("foo").ShouldBe("new-foo-value"); + + fooDto.BarDtos.Count.ShouldBe(1); + fooDto.BarDtos.First().Name.ShouldBe("new-bar-dto"); + fooDto.BarDtos.First().GetProperty("bar").ShouldBe("new-bar-value"); } }