diff --git a/framework/Volo.Abp.sln b/framework/Volo.Abp.sln
index fb59c91051..6957eb2baf 100644
--- a/framework/Volo.Abp.sln
+++ b/framework/Volo.Abp.sln
@@ -355,7 +355,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.AspNetCore.Compone
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Swashbuckle", "src\Volo.Abp.Swashbuckle\Volo.Abp.Swashbuckle.csproj", "{DD9519E0-5A68-48DC-A051-7BF2AC922F3E}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Json.Newtonsoft", "src\Volo.Abp.Json.Newtonsoft\Volo.Abp.Json.Newtonsoft.csproj", "{B5DEA857-1A22-4479-8441-E871D1BCBAB2}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Json.Tests", "test\Volo.Abp.Json.Tests\Volo.Abp.Json.Tests.csproj", "{00D07595-993C-40FC-BD90-0DD6331414D3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -1059,10 +1059,10 @@ Global
{DD9519E0-5A68-48DC-A051-7BF2AC922F3E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DD9519E0-5A68-48DC-A051-7BF2AC922F3E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DD9519E0-5A68-48DC-A051-7BF2AC922F3E}.Release|Any CPU.Build.0 = Release|Any CPU
- {B5DEA857-1A22-4479-8441-E871D1BCBAB2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {B5DEA857-1A22-4479-8441-E871D1BCBAB2}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {B5DEA857-1A22-4479-8441-E871D1BCBAB2}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {B5DEA857-1A22-4479-8441-E871D1BCBAB2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {00D07595-993C-40FC-BD90-0DD6331414D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {00D07595-993C-40FC-BD90-0DD6331414D3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {00D07595-993C-40FC-BD90-0DD6331414D3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {00D07595-993C-40FC-BD90-0DD6331414D3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1242,7 +1242,7 @@ Global
{B9D1ADCB-D552-4626-A1F1-78FF72C1E822} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{89840441-5A3A-4FD7-9CB4-E5B52FAEF72A} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{DD9519E0-5A68-48DC-A051-7BF2AC922F3E} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
- {B5DEA857-1A22-4479-8441-E871D1BCBAB2} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
+ {00D07595-993C-40FC-BD90-0DD6331414D3} = {447C8A77-E5F0-4538-8687-7383196D04EA}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BB97ECF4-9A84-433F-A80B-2A3285BDD1D5}
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo.Abp.AspNetCore.Mvc.csproj b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo.Abp.AspNetCore.Mvc.csproj
index fff97c83c3..a018dbbffd 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo.Abp.AspNetCore.Mvc.csproj
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo.Abp.AspNetCore.Mvc.csproj
@@ -28,6 +28,7 @@
+
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs
index 11a6ae9442..61d73cb48b 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs
@@ -136,7 +136,7 @@ namespace Volo.Abp.AspNetCore.Mvc
})
.AddViewLocalization(); //TODO: How to configure from the application? Also, consider to move to a UI module since APIs does not care about it.
- context.Services.TryAddEnumerable(ServiceDescriptor.Transient, AbpJsonOptionsSetup>());
+ mvcCoreBuilder.AddAbpHybridJson();
Configure(options =>
{
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonInputFormatter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonInputFormatter.cs
new file mode 100644
index 0000000000..4ad90bcad2
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonInputFormatter.cs
@@ -0,0 +1,38 @@
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Mvc.Formatters;
+using Microsoft.Extensions.DependencyInjection;
+using Volo.Abp.Json.SystemTextJson;
+
+namespace Volo.Abp.AspNetCore.Mvc.Json
+{
+ public class AbpHybridJsonInputFormatter : TextInputFormatter, IInputFormatterExceptionPolicy
+ {
+ public AbpHybridJsonInputFormatter()
+ {
+ SupportedEncodings.Add(UTF8EncodingWithoutBOM);
+ SupportedEncodings.Add(UTF16EncodingLittleEndian);
+
+ SupportedMediaTypes.Add(MediaTypeHeaderValues.ApplicationJson);
+ SupportedMediaTypes.Add(MediaTypeHeaderValues.TextJson);
+ SupportedMediaTypes.Add(MediaTypeHeaderValues.ApplicationAnyJsonSyntax);
+ }
+
+ public async override Task ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
+ {
+ return await GetTextInputFormatter(context).ReadRequestBodyAsync(context, encoding);
+ }
+
+ private TextInputFormatter GetTextInputFormatter(InputFormatterContext context)
+ {
+ if (context.HttpContext.RequestServices.GetRequiredService().CanHandle(context.ModelType))
+ {
+ return context.HttpContext.RequestServices.GetRequiredService();
+ }
+
+ return context.HttpContext.RequestServices.GetRequiredService();
+ }
+
+ public InputFormatterExceptionPolicy ExceptionPolicy => InputFormatterExceptionPolicy.MalformedInputExceptions;
+ }
+}
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonOutputFormatter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonOutputFormatter.cs
new file mode 100644
index 0000000000..7cf991be96
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonOutputFormatter.cs
@@ -0,0 +1,35 @@
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Mvc.Formatters;
+using Microsoft.Extensions.DependencyInjection;
+using Volo.Abp.Json.SystemTextJson;
+
+namespace Volo.Abp.AspNetCore.Mvc.Json
+{
+ public class AbpHybridJsonOutputFormatter : TextOutputFormatter
+ {
+ public AbpHybridJsonOutputFormatter()
+ {
+ SupportedEncodings.Add(Encoding.UTF8);
+ SupportedEncodings.Add(Encoding.Unicode);
+ SupportedMediaTypes.Add(MediaTypeHeaderValues.ApplicationJson);
+ SupportedMediaTypes.Add(MediaTypeHeaderValues.TextJson);
+ SupportedMediaTypes.Add(MediaTypeHeaderValues.ApplicationAnyJsonSyntax);
+ }
+
+ public async override Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
+ {
+ await GetTextInputFormatter(context).WriteResponseBodyAsync(context, selectedEncoding);
+ }
+
+ private TextOutputFormatter GetTextInputFormatter(OutputFormatterWriteContext context)
+ {
+ if (context.HttpContext.RequestServices.GetRequiredService().CanHandle(context.ObjectType))
+ {
+ return context.HttpContext.RequestServices.GetRequiredService();
+ }
+
+ return context.HttpContext.RequestServices.GetRequiredService();
+ }
+ }
+}
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 821b2c9218..b456204ed8 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
@@ -2,8 +2,7 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
-using Volo.Abp.Json.JsonConverters;
-using Volo.Abp.Json;
+using Volo.Abp.Json.SystemTextJson.JsonConverters;
namespace Volo.Abp.AspNetCore.Mvc.Json
{
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpMvcJsonContractResolver.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpMvcJsonContractResolver.cs
new file mode 100644
index 0000000000..2db8bc3f06
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpMvcJsonContractResolver.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Reflection;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Serialization;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.Json.Newtonsoft;
+using Volo.Abp.Reflection;
+using Volo.Abp.Timing;
+
+namespace Volo.Abp.AspNetCore.Mvc.Json
+{
+ public class AbpMvcJsonContractResolver : DefaultContractResolver, ITransientDependency
+ {
+ private readonly AbpJsonIsoDateTimeConverter _dateTimeConverter;
+
+ public AbpMvcJsonContractResolver(AbpJsonIsoDateTimeConverter dateTimeConverter)
+ {
+ _dateTimeConverter = dateTimeConverter;
+
+ NamingStrategy = new CamelCaseNamingStrategy();
+ }
+
+ protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
+ {
+ var property = base.CreateProperty(member, memberSerialization);
+
+ ModifyProperty(member, property);
+
+ return property;
+ }
+
+ protected virtual void ModifyProperty(MemberInfo member, JsonProperty property)
+ {
+ if (property.PropertyType != typeof(DateTime) && property.PropertyType != typeof(DateTime?))
+ {
+ return;
+ }
+
+ if (ReflectionHelper.GetSingleAttributeOfMemberOrDeclaringTypeOrDefault(member) == null)
+ {
+ property.Converter = _dateTimeConverter;
+ }
+ }
+ }
+}
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpMvcNewtonsoftJsonOptionsSetup.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpMvcNewtonsoftJsonOptionsSetup.cs
new file mode 100644
index 0000000000..48a09e2426
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpMvcNewtonsoftJsonOptionsSetup.cs
@@ -0,0 +1,22 @@
+using System;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Options;
+
+namespace Volo.Abp.AspNetCore.Mvc.Json
+{
+ public class AbpMvcNewtonsoftJsonOptionsSetup : IConfigureOptions
+ {
+ protected IServiceProvider ServiceProvider { get; }
+
+ public AbpMvcNewtonsoftJsonOptionsSetup(IServiceProvider serviceProvider)
+ {
+ ServiceProvider = serviceProvider;
+ }
+
+ public void Configure(MvcNewtonsoftJsonOptions options)
+ {
+ options.SerializerSettings.ContractResolver = ServiceProvider.GetRequiredService();
+ }
+ }
+}
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/MediaTypeHeaderValues.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/MediaTypeHeaderValues.cs
new file mode 100644
index 0000000000..d1f1b34b1a
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/MediaTypeHeaderValues.cs
@@ -0,0 +1,22 @@
+using Microsoft.Net.Http.Headers;
+
+namespace Volo.Abp.AspNetCore.Mvc.Json
+{
+ ///
+ /// https://github.com/dotnet/aspnetcore/blob/master/src/Mvc/Mvc.NewtonsoftJson/src/MediaTypeHeaderValues.cs
+ ///
+ internal static class MediaTypeHeaderValues
+ {
+ public static readonly MediaTypeHeaderValue ApplicationJson = MediaTypeHeaderValue.Parse("application/json").CopyAsReadOnly();
+
+ public static readonly MediaTypeHeaderValue TextJson = MediaTypeHeaderValue.Parse("text/json").CopyAsReadOnly();
+
+ public static readonly MediaTypeHeaderValue ApplicationAnyJsonSyntax = MediaTypeHeaderValue.Parse("application/*+json").CopyAsReadOnly();
+
+ public static readonly MediaTypeHeaderValue ApplicationXml = MediaTypeHeaderValue.Parse("application/xml").CopyAsReadOnly();
+
+ public static readonly MediaTypeHeaderValue TextXml = MediaTypeHeaderValue.Parse("text/xml").CopyAsReadOnly();
+
+ public static readonly MediaTypeHeaderValue ApplicationAnyXmlSyntax = MediaTypeHeaderValue.Parse("application/*+xml").CopyAsReadOnly();
+ }
+}
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/MvcCoreBuilderExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/MvcCoreBuilderExtensions.cs
new file mode 100644
index 0000000000..9eaa0c826a
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/MvcCoreBuilderExtensions.cs
@@ -0,0 +1,82 @@
+using System.Buffers;
+using System.Text.Json;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.Formatters;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection.Extensions;
+using Microsoft.Extensions.Options;
+using System.Text.Encodings.Web;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.ObjectPool;
+
+namespace Volo.Abp.AspNetCore.Mvc.Json
+{
+ public static class MvcCoreBuilderExtensions
+ {
+ public static IMvcCoreBuilder AddAbpHybridJson(this IMvcCoreBuilder builder)
+ {
+ //SystemTextJsonInputFormatter
+ builder.Services.AddTransient(provider =>
+ {
+ var jsonOptions = provider.GetRequiredService>();
+ var logger = provider.GetRequiredService().CreateLogger();
+ return new SystemTextJsonInputFormatter(jsonOptions.Value, logger);
+ });
+
+ //NewtonsoftJsonInputFormatter
+ builder.Services.AddTransient(provider =>
+ {
+ var jsonOptions = provider.GetRequiredService>().Value;
+
+ return new NewtonsoftJsonInputFormatter(
+ provider.GetRequiredService().CreateLogger(),
+ jsonOptions.SerializerSettings,
+ provider.GetRequiredService>(),
+ provider.GetRequiredService(),
+ provider.GetRequiredService>().Value,
+ jsonOptions);
+ });
+
+ //SystemTextJsonOutputFormatter
+ builder.Services.AddTransient(provider =>
+ {
+ var jsonSerializerOptions = provider.GetRequiredService>().Value.JsonSerializerOptions;
+ if (jsonSerializerOptions.Encoder is null)
+ {
+ // If the user hasn't explicitly configured the encoder, use the less strict encoder that does not encode all non-ASCII characters.
+ jsonSerializerOptions = new JsonSerializerOptions(jsonSerializerOptions)
+ {
+ Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
+ };
+ }
+ return new SystemTextJsonOutputFormatter(jsonSerializerOptions);
+ });
+
+ //NewtonsoftJsonOutputFormatter
+ builder.Services.AddTransient(provider =>
+ {
+ var jsonOptions = provider.GetRequiredService>().Value;
+ return new NewtonsoftJsonOutputFormatter(
+ jsonOptions.SerializerSettings,
+ provider.GetRequiredService>(),
+ provider.GetRequiredService>().Value);
+ });
+
+ builder.Services.TryAddEnumerable(ServiceDescriptor.Transient, AbpJsonOptionsSetup>());
+ builder.Services.TryAddEnumerable(ServiceDescriptor.Transient, AbpMvcNewtonsoftJsonOptionsSetup>());
+
+ builder.Services.Configure(options =>
+ {
+ options.InputFormatters.RemoveType();
+ options.InputFormatters.RemoveType();
+ options.InputFormatters.Add(new AbpHybridJsonInputFormatter());
+
+ options.OutputFormatters.RemoveType();
+ options.OutputFormatters.RemoveType();
+ options.OutputFormatters.Add(new AbpHybridJsonOutputFormatter());
+ });
+
+ return builder;
+ }
+ }
+}
diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/ValueConverters/AbpJsonValueConverter.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/ValueConverters/AbpJsonValueConverter.cs
index afce924d59..7378ab8eff 100644
--- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/ValueConverters/AbpJsonValueConverter.cs
+++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/ValueConverters/AbpJsonValueConverter.cs
@@ -1,6 +1,6 @@
using System.Text.Json;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
-using Volo.Abp.Json.JsonConverters;
+using Volo.Abp.Json.SystemTextJson.JsonConverters;
namespace Volo.Abp.EntityFrameworkCore.ValueConverters
{
diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/ValueConverters/ExtraPropertiesValueConverter.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/ValueConverters/ExtraPropertiesValueConverter.cs
index 00ce8459a6..661da95a19 100644
--- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/ValueConverters/ExtraPropertiesValueConverter.cs
+++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/ValueConverters/ExtraPropertiesValueConverter.cs
@@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Text.Json;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
-using Volo.Abp.Json.JsonConverters;
+using Volo.Abp.Json.SystemTextJson.JsonConverters;
using Volo.Abp.ObjectExtending;
namespace Volo.Abp.EntityFrameworkCore.ValueConverters
diff --git a/framework/src/Volo.Abp.Json.Newtonsoft/FodyWeavers.xml b/framework/src/Volo.Abp.Json.Newtonsoft/FodyWeavers.xml
deleted file mode 100644
index bc5a74a236..0000000000
--- a/framework/src/Volo.Abp.Json.Newtonsoft/FodyWeavers.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
diff --git a/framework/src/Volo.Abp.Json.Newtonsoft/FodyWeavers.xsd b/framework/src/Volo.Abp.Json.Newtonsoft/FodyWeavers.xsd
deleted file mode 100644
index 3f3946e282..0000000000
--- a/framework/src/Volo.Abp.Json.Newtonsoft/FodyWeavers.xsd
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.
-
-
-
-
- A comma-separated list of error codes that can be safely ignored in assembly verification.
-
-
-
-
- 'false' to turn off automatic generation of the XML Schema file.
-
-
-
-
-
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.Json.Newtonsoft/Volo.Abp.Json.Newtonsoft.csproj b/framework/src/Volo.Abp.Json.Newtonsoft/Volo.Abp.Json.Newtonsoft.csproj
deleted file mode 100644
index dd6cdc06ae..0000000000
--- a/framework/src/Volo.Abp.Json.Newtonsoft/Volo.Abp.Json.Newtonsoft.csproj
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
-
-
-
- netstandard2.0
- Volo.Abp.Json.Newtonsoft
- Volo.Abp.Json.Newtonsoft
- $(AssetTargetFallback);portable-net45+win8+wp8+wpa81;
- false
- false
- false
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/AbpJsonModule.cs b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/AbpJsonModule.cs
deleted file mode 100644
index b040f1afbb..0000000000
--- a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/AbpJsonModule.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.DependencyInjection.Extensions;
-using Microsoft.Extensions.Options;
-using Volo.Abp.Json;
-using Volo.Abp.Json.Newtonsoft;
-using Volo.Abp.Modularity;
-
-namespace Volo.Abp.Json
-{
- [DependsOn(typeof(AbpJsonModule))]
- public class AbpJsonNewtonsoftModule : AbpModule
- {
- public override void ConfigureServices(ServiceConfigurationContext context)
- {
- Configure(options =>
- {
- options.Converters.Add();
- });
- }
- }
-}
diff --git a/framework/src/Volo.Abp.Json/Volo.Abp.Json.csproj b/framework/src/Volo.Abp.Json/Volo.Abp.Json.csproj
index ddf8cfba65..1ef71853fa 100644
--- a/framework/src/Volo.Abp.Json/Volo.Abp.Json.csproj
+++ b/framework/src/Volo.Abp.Json/Volo.Abp.Json.csproj
@@ -16,6 +16,7 @@
+
diff --git a/framework/src/Volo.Abp.Json/Volo/Abp/Json/AbpHybridJsonSerializer.cs b/framework/src/Volo.Abp.Json/Volo/Abp/Json/AbpHybridJsonSerializer.cs
new file mode 100644
index 0000000000..6621ac8640
--- /dev/null
+++ b/framework/src/Volo.Abp.Json/Volo/Abp/Json/AbpHybridJsonSerializer.cs
@@ -0,0 +1,55 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Options;
+using Volo.Abp.DependencyInjection;
+
+namespace Volo.Abp.Json
+{
+ public class AbpHybridJsonSerializer : IJsonSerializer, ISingletonDependency
+ {
+ private readonly Lazy> _lazyProviders;
+ public List Providers => _lazyProviders.Value;
+
+ public AbpHybridJsonSerializer(IOptions options, IServiceProvider serviceProvider)
+ {
+ _lazyProviders = new Lazy>(
+ () => options.Value
+ .Providers
+ .Select(c => serviceProvider.GetRequiredService(c) as IJsonSerializerProvider)
+ .Reverse()
+ .ToList(),
+ true
+ );
+ }
+
+ public string Serialize(object obj, bool camelCase = true, bool indented = false)
+ {
+ var provider = GetSerializerProvider(obj.GetType());
+ return provider.Serialize(obj, camelCase, indented);
+ }
+
+ public T Deserialize(string jsonString, bool camelCase = true)
+ {
+ var provider = GetSerializerProvider(typeof(T));
+ return provider.Deserialize(jsonString, camelCase);
+ }
+
+ public object Deserialize(Type type, string jsonString, bool camelCase = true)
+ {
+ var provider = GetSerializerProvider(type);
+ return provider.Deserialize(type, jsonString, camelCase);
+ }
+
+ protected virtual IJsonSerializerProvider GetSerializerProvider(Type type)
+ {
+ foreach (var provider in Providers.Where(provider => provider.CanHandle(type)))
+ {
+ return provider;
+ }
+
+ throw new AbpException($"There is no IJsonSerializerProvider that can handle {type.GetFullNameWithAssemblyName()} types!");
+ }
+ }
+}
diff --git a/framework/src/Volo.Abp.Json/Volo/Abp/Json/AbpJsonModule.cs b/framework/src/Volo.Abp.Json/Volo/Abp/Json/AbpJsonModule.cs
index c5376d0f05..747f01732a 100644
--- a/framework/src/Volo.Abp.Json/Volo/Abp/Json/AbpJsonModule.cs
+++ b/framework/src/Volo.Abp.Json/Volo/Abp/Json/AbpJsonModule.cs
@@ -1,6 +1,8 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
+using Volo.Abp.Json.Newtonsoft;
+using Volo.Abp.Json.SystemTextJson;
using Volo.Abp.Modularity;
using Volo.Abp.Timing;
@@ -11,7 +13,20 @@ namespace Volo.Abp.Json
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
- context.Services.TryAddEnumerable(ServiceDescriptor.Transient, AbpJsonSerializerOptionsSetup>());
+ context.Services.TryAddEnumerable(ServiceDescriptor
+ .Transient,
+ AbpSystemTextJsonSerializerOptionsSetup>());
+
+ Configure(options =>
+ {
+ options.Providers.Add();
+ options.Providers.Add();
+ });
+
+ Configure(options =>
+ {
+ options.IgnoreAttributes.Add();
+ });
}
}
}
diff --git a/framework/src/Volo.Abp.Json/Volo/Abp/Json/AbpJsonOptions.cs b/framework/src/Volo.Abp.Json/Volo/Abp/Json/AbpJsonOptions.cs
index 239d7864cd..55a4683e26 100644
--- a/framework/src/Volo.Abp.Json/Volo/Abp/Json/AbpJsonOptions.cs
+++ b/framework/src/Volo.Abp.Json/Volo/Abp/Json/AbpJsonOptions.cs
@@ -1,4 +1,6 @@
-namespace Volo.Abp.Json
+using Volo.Abp.Collections;
+
+namespace Volo.Abp.Json
{
public class AbpJsonOptions
{
@@ -6,5 +8,12 @@
/// Used to set default value for the DateTimeFormat.
///
public string DefaultDateTimeFormat { get; set; }
+
+ public ITypeList Providers { get; }
+
+ public AbpJsonOptions()
+ {
+ Providers = new TypeList();
+ }
}
}
diff --git a/framework/src/Volo.Abp.Json/Volo/Abp/Json/IJsonSerializerProvider.cs b/framework/src/Volo.Abp.Json/Volo/Abp/Json/IJsonSerializerProvider.cs
new file mode 100644
index 0000000000..f844dc5fd0
--- /dev/null
+++ b/framework/src/Volo.Abp.Json/Volo/Abp/Json/IJsonSerializerProvider.cs
@@ -0,0 +1,15 @@
+using System;
+
+namespace Volo.Abp.Json
+{
+ public interface IJsonSerializerProvider
+ {
+ bool CanHandle(Type type);
+
+ string Serialize(object obj, bool camelCase = true, bool indented = false);
+
+ T Deserialize(string jsonString, bool camelCase = true);
+
+ object Deserialize(Type type, string jsonString, bool camelCase = true);
+ }
+}
diff --git a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpJsonIsoDateTimeConverter.cs b/framework/src/Volo.Abp.Json/Volo/Abp/Json/Newtonsoft/AbpJsonIsoDateTimeConverter.cs
similarity index 100%
rename from framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpJsonIsoDateTimeConverter.cs
rename to framework/src/Volo.Abp.Json/Volo/Abp/Json/Newtonsoft/AbpJsonIsoDateTimeConverter.cs
diff --git a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializerOptions.cs b/framework/src/Volo.Abp.Json/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializerOptions.cs
similarity index 100%
rename from framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializerOptions.cs
rename to framework/src/Volo.Abp.Json/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializerOptions.cs
diff --git a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/NewtonsoftJsonSerializer.cs b/framework/src/Volo.Abp.Json/Volo/Abp/Json/Newtonsoft/NewtonsoftJsonSerializerProvider.cs
similarity index 91%
rename from framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/NewtonsoftJsonSerializer.cs
rename to framework/src/Volo.Abp.Json/Volo/Abp/Json/Newtonsoft/NewtonsoftJsonSerializerProvider.cs
index e241484719..e33f9b155f 100644
--- a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/NewtonsoftJsonSerializer.cs
+++ b/framework/src/Volo.Abp.Json/Volo/Abp/Json/Newtonsoft/NewtonsoftJsonSerializerProvider.cs
@@ -9,15 +9,14 @@ using Volo.Abp.DependencyInjection;
namespace Volo.Abp.Json.Newtonsoft
{
- [Dependency(ReplaceServices = true)]
- public class NewtonsoftJsonSerializer : IJsonSerializer, ITransientDependency
+ public class NewtonsoftJsonSerializerProvider : IJsonSerializerProvider, ITransientDependency
{
private static readonly CamelCaseExceptDictionaryKeysResolver SharedCamelCaseExceptDictionaryKeysResolver =
new CamelCaseExceptDictionaryKeysResolver();
protected List Converters { get; }
- public NewtonsoftJsonSerializer(
+ public NewtonsoftJsonSerializerProvider(
IOptions options,
IServiceProvider serviceProvider)
{
@@ -27,6 +26,11 @@ namespace Volo.Abp.Json.Newtonsoft
.ToList();
}
+ public bool CanHandle(Type type)
+ {
+ return true;
+ }
+
public string Serialize(object obj, bool camelCase = true, bool indented = false)
{
return JsonConvert.SerializeObject(obj, CreateSerializerSettings(camelCase, indented));
diff --git a/framework/src/Volo.Abp.Json/Volo/Abp/Json/AbpJsonSerializerOptions.cs b/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerOptions.cs
similarity index 78%
rename from framework/src/Volo.Abp.Json/Volo/Abp/Json/AbpJsonSerializerOptions.cs
rename to framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerOptions.cs
index c1289ce159..1f986e688b 100644
--- a/framework/src/Volo.Abp.Json/Volo/Abp/Json/AbpJsonSerializerOptions.cs
+++ b/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerOptions.cs
@@ -1,12 +1,12 @@
using System.Text.Json;
-namespace Volo.Abp.Json
+namespace Volo.Abp.Json.SystemTextJson
{
- public class AbpJsonSerializerOptions
+ public class AbpSystemTextJsonSerializerOptions
{
public JsonSerializerOptions JsonSerializerOptions { get; }
- public AbpJsonSerializerOptions()
+ public AbpSystemTextJsonSerializerOptions()
{
//TODO:Defaults?
//https://github.com/dotnet/aspnetcore/blob/master/src/Mvc/Mvc.Core/src/JsonOptions.cs#L18
diff --git a/framework/src/Volo.Abp.Json/Volo/Abp/Json/AbpJsonSerializerOptionsSetup.cs b/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerOptionsSetup.cs
similarity index 59%
rename from framework/src/Volo.Abp.Json/Volo/Abp/Json/AbpJsonSerializerOptionsSetup.cs
rename to framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerOptionsSetup.cs
index 16e8119731..4b56997d47 100644
--- a/framework/src/Volo.Abp.Json/Volo/Abp/Json/AbpJsonSerializerOptionsSetup.cs
+++ b/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerOptionsSetup.cs
@@ -1,20 +1,21 @@
using System;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
-using Volo.Abp.Json.JsonConverters;
+using Volo.Abp.Json.SystemTextJson;
+using Volo.Abp.Json.SystemTextJson.JsonConverters;
namespace Volo.Abp.Json
{
- public class AbpJsonSerializerOptionsSetup : IConfigureOptions
+ public class AbpSystemTextJsonSerializerOptionsSetup : IConfigureOptions
{
protected IServiceProvider ServiceProvider { get; }
- public AbpJsonSerializerOptionsSetup(IServiceProvider serviceProvider)
+ public AbpSystemTextJsonSerializerOptionsSetup(IServiceProvider serviceProvider)
{
ServiceProvider = serviceProvider;
}
- public void Configure(AbpJsonSerializerOptions options)
+ public void Configure(AbpSystemTextJsonSerializerOptions options)
{
options.JsonSerializerOptions.Converters.Add(ServiceProvider.GetRequiredService());
options.JsonSerializerOptions.Converters.Add(ServiceProvider.GetRequiredService());
diff --git a/framework/src/Volo.Abp.Json/Volo/Abp/Json/JsonConverters/AbpDateTimeConverter.cs b/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpDateTimeConverter.cs
similarity index 81%
rename from framework/src/Volo.Abp.Json/Volo/Abp/Json/JsonConverters/AbpDateTimeConverter.cs
rename to framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpDateTimeConverter.cs
index 29e99f285e..a87add029e 100644
--- a/framework/src/Volo.Abp.Json/Volo/Abp/Json/JsonConverters/AbpDateTimeConverter.cs
+++ b/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpDateTimeConverter.cs
@@ -5,7 +5,7 @@ using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Timing;
-namespace Volo.Abp.Json.JsonConverters
+namespace Volo.Abp.Json.SystemTextJson.JsonConverters
{
public class AbpDateTimeConverter : JsonConverter, ITransientDependency
{
@@ -27,11 +27,11 @@ namespace Volo.Abp.Json.JsonConverters
{
if (_options.DefaultDateTimeFormat.IsNullOrWhiteSpace())
{
- writer.WriteStringValue(value);
+ writer.WriteStringValue(_clock.Normalize(value));
}
else
{
- writer.WriteStringValue(value.ToString(_options.DefaultDateTimeFormat));
+ writer.WriteStringValue(_clock.Normalize(value).ToString(_options.DefaultDateTimeFormat));
}
}
}
diff --git a/framework/src/Volo.Abp.Json/Volo/Abp/Json/JsonConverters/AbpNullableDateTimeConverter.cs b/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpNullableDateTimeConverter.cs
similarity index 84%
rename from framework/src/Volo.Abp.Json/Volo/Abp/Json/JsonConverters/AbpNullableDateTimeConverter.cs
rename to framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpNullableDateTimeConverter.cs
index f061b94cf5..bad650b4d8 100644
--- a/framework/src/Volo.Abp.Json/Volo/Abp/Json/JsonConverters/AbpNullableDateTimeConverter.cs
+++ b/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpNullableDateTimeConverter.cs
@@ -5,7 +5,7 @@ using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Timing;
-namespace Volo.Abp.Json.JsonConverters
+namespace Volo.Abp.Json.SystemTextJson.JsonConverters
{
public class AbpNullableDateTimeConverter : JsonConverter, ITransientDependency
{
@@ -38,11 +38,11 @@ namespace Volo.Abp.Json.JsonConverters
{
if (_options.DefaultDateTimeFormat.IsNullOrWhiteSpace())
{
- writer.WriteStringValue(value.Value);
+ writer.WriteStringValue(_clock.Normalize(value.Value));
}
else
{
- writer.WriteStringValue(value.Value.ToString(_options.DefaultDateTimeFormat));
+ writer.WriteStringValue(_clock.Normalize(value.Value).ToString(_options.DefaultDateTimeFormat));
}
}
}
diff --git a/framework/src/Volo.Abp.Json/Volo/Abp/Json/JsonConverters/ObjectToInferredTypesConverter.cs b/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/ObjectToInferredTypesConverter.cs
similarity index 96%
rename from framework/src/Volo.Abp.Json/Volo/Abp/Json/JsonConverters/ObjectToInferredTypesConverter.cs
rename to framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/ObjectToInferredTypesConverter.cs
index c7497cfa60..02fa9bbaff 100644
--- a/framework/src/Volo.Abp.Json/Volo/Abp/Json/JsonConverters/ObjectToInferredTypesConverter.cs
+++ b/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/ObjectToInferredTypesConverter.cs
@@ -2,7 +2,7 @@
using System.Text.Json;
using System.Text.Json.Serialization;
-namespace Volo.Abp.Json.JsonConverters
+namespace Volo.Abp.Json.SystemTextJson.JsonConverters
{
///
/// https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-converters-how-to#deserialize-inferred-types-to-object-properties
diff --git a/framework/src/Volo.Abp.Json/Volo/Abp/Json/AbpJsonSerializer.cs b/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/SystemTextJsonSerializerProvider.cs
similarity index 67%
rename from framework/src/Volo.Abp.Json/Volo/Abp/Json/AbpJsonSerializer.cs
rename to framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/SystemTextJsonSerializerProvider.cs
index 250111fee2..5a3429bff1 100644
--- a/framework/src/Volo.Abp.Json/Volo/Abp/Json/AbpJsonSerializer.cs
+++ b/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/SystemTextJsonSerializerProvider.cs
@@ -2,18 +2,27 @@
using System.Text.Json;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
+using Volo.Abp.Json.SystemTextJson;
namespace Volo.Abp.Json
{
- public class AbpJsonSerializer : IJsonSerializer, ITransientDependency
+ public class SystemTextJsonSerializerProvider : IJsonSerializerProvider, ITransientDependency
{
- protected AbpJsonSerializerOptions Options { get; }
+ protected AbpSystemTextJsonSerializerOptions Options { get; }
- public AbpJsonSerializer(IOptions options)
+ protected SystemTextJsonSupportTypes SystemTextJsonSupportTypes { get; }
+
+ public SystemTextJsonSerializerProvider(IOptions options, SystemTextJsonSupportTypes systemTextJsonSupportTypes)
{
+ SystemTextJsonSupportTypes = systemTextJsonSupportTypes;
Options = options.Value;
}
+ public bool CanHandle(Type type)
+ {
+ return SystemTextJsonSupportTypes.CanHandle(type);
+ }
+
public string Serialize(object obj, bool camelCase = true, bool indented = false)
{
return JsonSerializer.Serialize(obj, CreateJsonSerializerOptions(camelCase, indented));
diff --git a/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/SystemTextJsonSupportTypes.cs b/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/SystemTextJsonSupportTypes.cs
new file mode 100644
index 0000000000..c2061e5b27
--- /dev/null
+++ b/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/SystemTextJsonSupportTypes.cs
@@ -0,0 +1,62 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.Extensions.Options;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.Reflection;
+using Volo.Abp.Timing;
+
+namespace Volo.Abp.Json.SystemTextJson
+{
+ public class SystemTextJsonSupportTypes : ITransientDependency
+ {
+ private static readonly List CacheTypes = new List();
+
+ private readonly SystemTextJsonSupportTypesOptions Options;
+
+ public SystemTextJsonSupportTypes(IOptions options)
+ {
+ Options = options.Value;
+ }
+
+ public bool CanHandle(Type type)
+ {
+ if (CacheTypes.Any(x => x == type))
+ {
+ return false;
+ }
+
+ if (type.GetCustomAttributes(true).Any(x => Options.IgnoreAttributes.Any(a => a == x.GetType())))
+ {
+ CacheTypes.Add(type);
+ return false;
+ }
+
+ if (type.DeclaringType != null && type.DeclaringType.GetCustomAttributes(true).Any(x => Options.IgnoreAttributes.Any(a => a == x.GetType())))
+ {
+ CacheTypes.Add(type.DeclaringType);
+ return false;
+ }
+
+ foreach (var propertyInfo in type.GetProperties())
+ {
+ if (propertyInfo.IsDefined(typeof(DisableDateTimeNormalizationAttribute), true))
+ {
+ CacheTypes.Add(propertyInfo.GetType());
+ return false;
+ }
+
+ if (!TypeHelper.IsPrimitiveExtended(type))
+ {
+ if (!CanHandle(propertyInfo.PropertyType))
+ {
+ CacheTypes.Add(propertyInfo.PropertyType);
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+ }
+}
diff --git a/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/SystemTextJsonSupportTypesOptions.cs b/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/SystemTextJsonSupportTypesOptions.cs
new file mode 100644
index 0000000000..33ad53b997
--- /dev/null
+++ b/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/SystemTextJsonSupportTypesOptions.cs
@@ -0,0 +1,15 @@
+using System;
+using Volo.Abp.Collections;
+
+namespace Volo.Abp.Json.SystemTextJson
+{
+ public class SystemTextJsonSupportTypesOptions
+ {
+ public ITypeList IgnoreAttributes;
+
+ public SystemTextJsonSupportTypesOptions()
+ {
+ IgnoreAttributes = new TypeList();
+ }
+ }
+}
diff --git a/framework/test/Volo.Abp.Json.Tests/Volo.Abp.Json.Tests.csproj b/framework/test/Volo.Abp.Json.Tests/Volo.Abp.Json.Tests.csproj
new file mode 100644
index 0000000000..fbc56e6ac2
--- /dev/null
+++ b/framework/test/Volo.Abp.Json.Tests/Volo.Abp.Json.Tests.csproj
@@ -0,0 +1,16 @@
+
+
+
+
+
+ net5.0
+
+
+
+
+
+
+
+
+
+
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
new file mode 100644
index 0000000000..5c9065ad80
--- /dev/null
+++ b/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpJsonTestBase.cs
@@ -0,0 +1,12 @@
+using Volo.Abp.Testing;
+
+namespace Volo.Abp.Json
+{
+ public abstract class AbpJsonTestBase : AbpIntegratedTest
+ {
+ protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options)
+ {
+ options.UseAutofac();
+ }
+ }
+}
diff --git a/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpJsonTestModule.cs b/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpJsonTestModule.cs
new file mode 100644
index 0000000000..ddbc08ac3f
--- /dev/null
+++ b/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpJsonTestModule.cs
@@ -0,0 +1,15 @@
+using Volo.Abp.Autofac;
+using Volo.Abp.Modularity;
+
+namespace Volo.Abp.Json
+{
+ [DependsOn(
+ typeof(AbpAutofacModule),
+ typeof(AbpJsonModule),
+ typeof(AbpTestBaseModule)
+ )]
+ public class AbpJsonTestModule : AbpModule
+ {
+
+ }
+}
diff --git a/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/SystemTextJsonSupportTypes_Tests.cs b/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/SystemTextJsonSupportTypes_Tests.cs
new file mode 100644
index 0000000000..b21cb94653
--- /dev/null
+++ b/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/SystemTextJsonSupportTypes_Tests.cs
@@ -0,0 +1,65 @@
+using System;
+using Shouldly;
+using Volo.Abp.Json.SystemTextJson;
+using Volo.Abp.Timing;
+using Xunit;
+
+namespace Volo.Abp.Json
+{
+ public class SystemTextJsonSupportTypes_Tests : AbpJsonTestBase
+ {
+ private readonly SystemTextJsonSupportTypes _systemTextJsonSupportTypes;
+
+ public SystemTextJsonSupportTypes_Tests()
+ {
+ _systemTextJsonSupportTypes = GetRequiredService();
+ }
+
+ [Fact]
+ public void Test()
+ {
+ _systemTextJsonSupportTypes.CanHandle(typeof(MyClass)).ShouldBeFalse();
+ _systemTextJsonSupportTypes.CanHandle(typeof(MyClass2)).ShouldBeFalse();
+ _systemTextJsonSupportTypes.CanHandle(typeof(MyClass3)).ShouldBeFalse();
+ _systemTextJsonSupportTypes.CanHandle(typeof(MyClass4)).ShouldBeFalse();
+
+ _systemTextJsonSupportTypes.CanHandle(typeof(MyClass5)).ShouldBeTrue();
+ _systemTextJsonSupportTypes.CanHandle(typeof(MyClass6)).ShouldBeTrue();
+ }
+
+ [DisableDateTimeNormalization]
+ class MyClass
+ {
+ public DateTime Prop1 { get; set; }
+ }
+
+ class MyClass2
+ {
+ [DisableDateTimeNormalization]
+ public DateTime Prop1 { get; set; }
+ }
+
+ class MyClass3
+ {
+ public MyClass4 Prop1 { get; set; }
+ }
+
+ class MyClass4
+ {
+ [DisableDateTimeNormalization]
+ public DateTime Prop1 { get; set; }
+ }
+
+ class MyClass5
+ {
+ public DateTime Prop1 { get; set; }
+
+ public MyClass6 Prop2 { get; set; }
+ }
+
+ class MyClass6
+ {
+ public DateTime Prop1 { get; set; }
+ }
+ }
+}
diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/AbpFeatureManagementApplicationContractsModule.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/AbpFeatureManagementApplicationContractsModule.cs
index c3ca6c2adc..32939a2430 100644
--- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/AbpFeatureManagementApplicationContractsModule.cs
+++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/AbpFeatureManagementApplicationContractsModule.cs
@@ -2,6 +2,7 @@
using Volo.Abp.Application;
using Volo.Abp.FeatureManagement.JsonConverters;
using Volo.Abp.Json;
+using Volo.Abp.Json.SystemTextJson;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
@@ -21,7 +22,7 @@ namespace Volo.Abp.FeatureManagement
options.FileSets.AddEmbedded();
});
- Configure(options =>
+ Configure(options =>
{
options.JsonSerializerOptions.Converters.AddIfNotContains(new StringValueTypeJsonConverter());
});
diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/JsonConverters/ValueValidatorJsonConverter.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/JsonConverters/ValueValidatorJsonConverter.cs
index bfea58b078..9d94cf8b55 100644
--- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/JsonConverters/ValueValidatorJsonConverter.cs
+++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/JsonConverters/ValueValidatorJsonConverter.cs
@@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
-using Volo.Abp.Json.JsonConverters;
+using Volo.Abp.Json.SystemTextJson.JsonConverters;
using Volo.Abp.Validation.StringValues;
namespace Volo.Abp.FeatureManagement.JsonConverters
diff --git a/nupkg/common.ps1 b/nupkg/common.ps1
index 3df9140805..29cb13d9f3 100644
--- a/nupkg/common.ps1
+++ b/nupkg/common.ps1
@@ -109,7 +109,6 @@ $projects = (
"framework/src/Volo.Abp.Http",
"framework/src/Volo.Abp.IdentityModel",
"framework/src/Volo.Abp.Json",
- "framework/src/Volo.Abp.Json.Newtonsoft",
"framework/src/Volo.Abp.Ldap",
"framework/src/Volo.Abp.Localization.Abstractions",
"framework/src/Volo.Abp.MailKit",