diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpJsonOptionsSetup.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpJsonOptionsSetup.cs index bc5f4bef28..43a9c04d32 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpJsonOptionsSetup.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpJsonOptionsSetup.cs @@ -29,7 +29,7 @@ namespace Volo.Abp.AspNetCore.Mvc.Json options.JsonSerializerOptions.Converters.Add(new AbpStringToBooleanConverter()); options.JsonSerializerOptions.Converters.Add(new ObjectToInferredTypesConverter()); - options.JsonSerializerOptions.Converters.Add(new AbpExtraPropertyDictionaryJsonConverterFactory()); + options.JsonSerializerOptions.Converters.Add(new AbpHasExtraPropertiesJsonConverterFactory()); } } } diff --git a/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerOptionsSetup.cs b/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerOptionsSetup.cs index a5d6d111b1..9fd156439b 100644 --- a/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerOptionsSetup.cs +++ b/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerOptionsSetup.cs @@ -23,7 +23,7 @@ namespace Volo.Abp.Json.SystemTextJson options.JsonSerializerOptions.Converters.Add(new AbpStringToBooleanConverter()); options.JsonSerializerOptions.Converters.Add(new ObjectToInferredTypesConverter()); - options.JsonSerializerOptions.Converters.Add(new AbpExtraPropertyDictionaryJsonConverterFactory()); + options.JsonSerializerOptions.Converters.Add(new AbpHasExtraPropertiesJsonConverterFactory()); } } } diff --git a/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpExtraPropertyDictionaryJsonConverterFactory.cs b/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpExtraPropertyDictionaryJsonConverterFactory.cs deleted file mode 100644 index 9dabd86b85..0000000000 --- a/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpExtraPropertyDictionaryJsonConverterFactory.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using System.Reflection; -using System.Text.Json; -using System.Text.Json.Serialization; -using Volo.Abp.ObjectExtending; - -namespace Volo.Abp.Json.SystemTextJson.JsonConverters -{ - public class AbpExtraPropertyDictionaryJsonConverterFactory : JsonConverterFactory - { - public override bool CanConvert(Type typeToConvert) - { - return typeToConvert == typeof(ExtensibleObject) || typeToConvert.IsSubclassOf(typeof(ExtensibleObject)); - } - - public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) - { - return (JsonConverter) Activator.CreateInstance( - typeof(AbpExtraPropertyDictionaryJsonConverter<>).MakeGenericType(typeToConvert), - BindingFlags.Instance | BindingFlags.Public, - binder: null, - null, - culture: null)!; - } - } -} diff --git a/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpExtraPropertyDictionaryJsonConverter.cs b/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpHasExtraPropertiesJsonConverter.cs similarity index 73% rename from framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpExtraPropertyDictionaryJsonConverter.cs rename to framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpHasExtraPropertiesJsonConverter.cs index f816cb6396..40227dd5c3 100644 --- a/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpExtraPropertyDictionaryJsonConverter.cs +++ b/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpHasExtraPropertiesJsonConverter.cs @@ -1,30 +1,27 @@ using System; -using System.Collections.Generic; using System.Linq; using System.Text.Json; using System.Text.Json.Serialization; using Volo.Abp.Data; -using Volo.Abp.ObjectExtending; namespace Volo.Abp.Json.SystemTextJson.JsonConverters { - public class AbpExtraPropertyDictionaryJsonConverter : JsonConverter - where T : ExtensibleObject + public class AbpHasExtraPropertiesJsonConverter : JsonConverter + where T : IHasExtraProperties { public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { var newOptions = JsonSerializerOptionsHelper.Create(options, x => x == this || - x.GetType() == typeof(AbpExtraPropertyDictionaryJsonConverterFactory)); + x.GetType() == typeof(AbpHasExtraPropertiesJsonConverterFactory)); var rootElement = JsonDocument.ParseValue(ref reader).RootElement; var extensibleObject = JsonSerializer.Deserialize(rootElement.GetRawText(), newOptions); + var extraProperties = rootElement.EnumerateObject().FirstOrDefault(x => - x.Name.Equals(nameof(ExtensibleObject.ExtraProperties), StringComparison.OrdinalIgnoreCase)) + x.Name.Equals(nameof(IHasExtraProperties.ExtraProperties), StringComparison.OrdinalIgnoreCase)) .Value.GetRawText(); - var extraPropertyDictionary = JsonSerializer.Deserialize(extraProperties, typeof(ExtraPropertyDictionary), newOptions); - ObjectHelper.TrySetProperty(extensibleObject, x => x.ExtraProperties, () => extraPropertyDictionary); return extensibleObject; @@ -34,7 +31,7 @@ namespace Volo.Abp.Json.SystemTextJson.JsonConverters { var newOptions = JsonSerializerOptionsHelper.Create(options, x => x == this || - x.GetType() == typeof(AbpExtraPropertyDictionaryJsonConverterFactory)); + x.GetType() == typeof(AbpHasExtraPropertiesJsonConverterFactory)); JsonSerializer.Serialize(writer, value, newOptions); } 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 new file mode 100644 index 0000000000..f654504e05 --- /dev/null +++ b/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpHasExtraPropertiesJsonConverterFactory.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Concurrent; +using System.Reflection; +using System.Text.Json; +using System.Text.Json.Serialization; +using Volo.Abp.Data; + +namespace Volo.Abp.Json.SystemTextJson.JsonConverters +{ + public class AbpHasExtraPropertiesJsonConverterFactory : JsonConverterFactory + { + private static readonly ConcurrentDictionary CachedTypes = new ConcurrentDictionary(); + + public override bool CanConvert(Type typeToConvert) + { + //Only for private or protected ExtraProperties. + if (typeof(IHasExtraProperties).IsAssignableFrom(typeToConvert)) + { + return CachedTypes.GetOrAdd(typeToConvert, type => + { + var property = type.GetProperty(nameof(IHasExtraProperties.ExtraProperties)); + if (property != null) + { + var setMethod = property.GetSetMethod(true); + return setMethod != null && (setMethod.IsPrivate || setMethod.IsFamily); + } + + return false; + }); + } + + return false; + } + + public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) + { + return (JsonConverter) Activator.CreateInstance( + typeof(AbpHasExtraPropertiesJsonConverter<>).MakeGenericType(typeToConvert), + BindingFlags.Instance | BindingFlags.Public, + binder: null, + null, + culture: null)!; + } + } +}