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 a48d5148bd..366906f66e 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 @@ -25,7 +25,7 @@ namespace Volo.Abp.AspNetCore.Mvc.Json options.JsonSerializerOptions.Converters.Add(ServiceProvider.GetRequiredService()); options.JsonSerializerOptions.Converters.Add(ServiceProvider.GetRequiredService()); - options.JsonSerializerOptions.Converters.Add(new AbpStringToEnumConverter()); + options.JsonSerializerOptions.Converters.Add(new AbpStringToEnumFactory()); options.JsonSerializerOptions.Converters.Add(new AbpStringToBooleanConverter()); } } 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 9702d4078f..626e084ca6 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 @@ -19,7 +19,7 @@ namespace Volo.Abp.Json.SystemTextJson options.JsonSerializerOptions.Converters.Add(ServiceProvider.GetRequiredService()); options.JsonSerializerOptions.Converters.Add(ServiceProvider.GetRequiredService()); - options.JsonSerializerOptions.Converters.Add(new AbpStringToEnumConverter()); + options.JsonSerializerOptions.Converters.Add(new AbpStringToEnumFactory()); options.JsonSerializerOptions.Converters.Add(new AbpStringToBooleanConverter()); } } diff --git a/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpStringToEnumConverter.cs b/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpStringToEnumConverter.cs index 0de49a76b2..cead695538 100644 --- a/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpStringToEnumConverter.cs +++ b/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpStringToEnumConverter.cs @@ -1,16 +1,19 @@ using System; +using System.Collections.Generic; using System.Text.Json; using System.Text.Json.Serialization; namespace Volo.Abp.Json.SystemTextJson.JsonConverters { - public class AbpStringToEnumConverter : JsonConverter + public class AbpStringToEnumConverter : JsonConverter + where T : struct, Enum { private readonly JsonStringEnumConverter _innerJsonStringEnumConverter; public AbpStringToEnumConverter() : this(namingPolicy: null, allowIntegerValues: true) { + } public AbpStringToEnumConverter(JsonNamingPolicy namingPolicy = null, bool allowIntegerValues = true) @@ -23,18 +26,18 @@ namespace Volo.Abp.Json.SystemTextJson.JsonConverters return typeToConvert.IsEnum; } - public override object Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { var newOptions = new JsonSerializerOptions(options); - newOptions.Converters.Remove(this); + newOptions.Converters.RemoveAll(x => x == this || x.GetType() == typeof(AbpStringToEnumFactory)); newOptions.Converters.Add(_innerJsonStringEnumConverter.CreateConverter(typeToConvert, newOptions)); - return JsonSerializer.Deserialize(ref reader, typeToConvert, newOptions); + return JsonSerializer.Deserialize(ref reader, newOptions); } - public override void Write(Utf8JsonWriter writer, object value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) { var newOptions = new JsonSerializerOptions(options); - newOptions.Converters.Remove(this); + newOptions.Converters.RemoveAll(x => x == this || x.GetType() == typeof(AbpStringToEnumFactory)); JsonSerializer.Serialize(writer, value, newOptions); } } diff --git a/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpStringToEnumFactory.cs b/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpStringToEnumFactory.cs new file mode 100644 index 0000000000..f85d74e1c3 --- /dev/null +++ b/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpStringToEnumFactory.cs @@ -0,0 +1,40 @@ +using System; +using System.Reflection; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Volo.Abp.Json.SystemTextJson.JsonConverters +{ + public class AbpStringToEnumFactory : JsonConverterFactory + { + private readonly JsonNamingPolicy _namingPolicy; + private readonly bool _allowIntegerValues; + + public AbpStringToEnumFactory() + : this(namingPolicy: null, allowIntegerValues: true) + { + + } + + public AbpStringToEnumFactory(JsonNamingPolicy namingPolicy, bool allowIntegerValues) + { + _namingPolicy = namingPolicy; + _allowIntegerValues = allowIntegerValues; + } + + public override bool CanConvert(Type typeToConvert) + { + return typeToConvert.IsEnum; + } + + public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) + { + return (JsonConverter) Activator.CreateInstance( + typeof(AbpStringToEnumConverter<>).MakeGenericType(typeToConvert), + BindingFlags.Instance | BindingFlags.Public, + binder: null, + new object[] { _namingPolicy, _allowIntegerValues }, + culture: null)!; + } + } +} diff --git a/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpHybridJsonSerializer_Tests.cs b/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpHybridJsonSerializer_Tests.cs index 98f8acc7b4..eb44e51820 100644 --- a/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpHybridJsonSerializer_Tests.cs +++ b/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpHybridJsonSerializer_Tests.cs @@ -1,10 +1,8 @@ using System; using System.Collections.Generic; -using System.Reflection; using System.Text.Json; using Microsoft.Extensions.DependencyInjection; using Newtonsoft.Json; -using Newtonsoft.Json.Serialization; using Shouldly; using Volo.Abp.DependencyInjection; using Volo.Abp.Json.Newtonsoft; 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 new file mode 100644 index 0000000000..143400c58c --- /dev/null +++ b/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpSystemTextJsonSerializerProvider_Tests.cs @@ -0,0 +1,63 @@ +using Shouldly; +using Volo.Abp.Json.SystemTextJson; +using Xunit; + +namespace Volo.Abp.Json +{ + public class AbpSystemTextJsonSerializerProvider_Tests : AbpJsonTestBase + { + private readonly AbpSystemTextJsonSerializerProvider _jsonSerializer; + + public AbpSystemTextJsonSerializerProvider_Tests() + { + _jsonSerializer = GetRequiredService(); + } + + [Fact] + public void Serialize_Deserialize_With_Boolean() + { + var json = "{\"name\":\"abp\",\"IsDeleted\":\"fAlSe\"}"; + var file = _jsonSerializer.Deserialize(json); + file.Name.ShouldBe("abp"); + file.IsDeleted.ShouldBeFalse(); + + file.IsDeleted = false; + var newJson = _jsonSerializer.Serialize(file); + newJson.ShouldBe("{\"name\":\"abp\",\"isDeleted\":false}"); + } + + [Fact] + public void Serialize_Deserialize_With_Enum() + { + var json = "{\"name\":\"abp\",\"type\":\"Exe\"}"; + var file = _jsonSerializer.Deserialize(json); + file.Name.ShouldBe("abp"); + file.Type.ShouldBe(FileType.Exe); + + var newJson = _jsonSerializer.Serialize(file); + newJson.ShouldBe("{\"name\":\"abp\",\"type\":2}"); + } + + class FileWithBoolean + { + public string Name { get; set; } + + public bool IsDeleted { get; set; } + + } + + class FileWithEnum + { + public string Name { get; set; } + + public FileType Type { get; set; } + } + + + enum FileType + { + Zip = 0, + Exe = 2 + } + } +}