diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpAspNetCoreMvcNewtonsoftModule.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpAspNetCoreMvcNewtonsoftModule.cs index ccf25979db..f195f98bf4 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpAspNetCoreMvcNewtonsoftModule.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpAspNetCoreMvcNewtonsoftModule.cs @@ -1,10 +1,14 @@ -using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Formatters; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.ObjectPool; using Microsoft.Extensions.Options; +using Newtonsoft.Json; using Volo.Abp.AspNetCore.Mvc.Json; +using Volo.Abp.Json.Newtonsoft; using Volo.Abp.Modularity; namespace Volo.Abp.AspNetCore.Mvc.NewtonsoftJson; @@ -14,29 +18,30 @@ public class AbpAspNetCoreMvcNewtonsoftModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { - var options = context.Services.ExecutePreConfiguredActions(); + context.Services.TryAddSingleton(); - if (options.UseHybridSerializer) + Configure(mvcOptions => { - context.Services.TryAddSingleton(); + mvcOptions.InputFormatters.RemoveType(); + mvcOptions.OutputFormatters.RemoveType(); + }); - Configure(mvcOptions => - { - mvcOptions.InputFormatters.RemoveType(); - mvcOptions.OutputFormatters.RemoveType(); - }); + Configure(formatterOptions => + { + formatterOptions.TextInputFormatters.Add(); + formatterOptions.TextOutputFormatters.Add(); + }); - Configure(formatterOptions => + context.Services.AddOptions() + .Configure((options, serviceProvider) => { - formatterOptions.TextInputFormatters.Add(); - formatterOptions.TextOutputFormatters.Add(); - }); - } - else - { - context.Services.AddMvcCore().AddNewtonsoftJson(); - } + options.SerializerSettings.ContractResolver = serviceProvider.GetRequiredService(); + + var converters = serviceProvider.GetRequiredService>().Value + .Converters.Select(converterType => serviceProvider.GetRequiredService(converterType).As()) + .ToList(); - context.Services.TryAddEnumerable(ServiceDescriptor.Transient, AbpMvcNewtonsoftJsonOptionsSetup>()); + options.SerializerSettings.Converters.InsertRange(0, converters); + }); } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpAspNetCoreMvcNewtonsoftOptions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpAspNetCoreMvcNewtonsoftOptions.cs deleted file mode 100644 index 63d11b00b7..0000000000 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpAspNetCoreMvcNewtonsoftOptions.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Volo.Abp.AspNetCore.Mvc.NewtonsoftJson; - -public class AbpAspNetCoreMvcNewtonsoftOptions -{ - public bool UseHybridSerializer { get; set; } - - public AbpAspNetCoreMvcNewtonsoftOptions() - { - UseHybridSerializer = true; - } -} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpMvcNewtonsoftJsonOptionsSetup.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpMvcNewtonsoftJsonOptionsSetup.cs deleted file mode 100644 index ab7eaf2244..0000000000 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpMvcNewtonsoftJsonOptionsSetup.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Options; -using Newtonsoft.Json; -using Volo.Abp.Json.Newtonsoft; - -namespace Volo.Abp.AspNetCore.Mvc.NewtonsoftJson; - -public class AbpMvcNewtonsoftJsonOptionsSetup : IConfigureOptions -{ - private readonly IServiceProvider _serviceProvider; - - public AbpMvcNewtonsoftJsonOptionsSetup(IServiceProvider serviceProvider) - { - _serviceProvider = serviceProvider; - } - - public void Configure(MvcNewtonsoftJsonOptions options) - { - options.SerializerSettings.ContractResolver = _serviceProvider.GetRequiredService(); - - var converters = _serviceProvider.GetRequiredService>().Value - .Converters.Select(converterType => _serviceProvider.GetRequiredService(converterType).As()) - .ToList(); - - options.SerializerSettings.Converters.InsertRange(0, converters); - } -} 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 deleted file mode 100644 index 05c57ee5a7..0000000000 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpJsonOptionsSetup.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using System.Text.Json; -using System.Text.Json.Serialization; -using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Options; -using Volo.Abp.Json.SystemTextJson; -using Volo.Abp.Json.SystemTextJson.JsonConverters; - -namespace Volo.Abp.AspNetCore.Mvc.Json; - -public class AbpJsonOptionsSetup : IConfigureOptions -{ - protected IServiceProvider ServiceProvider { get; } - - public AbpJsonOptionsSetup(IServiceProvider serviceProvider) - { - ServiceProvider = serviceProvider; - } - - public void Configure(JsonOptions options) - { - options.JsonSerializerOptions.ReadCommentHandling = JsonCommentHandling.Skip; - options.JsonSerializerOptions.AllowTrailingCommas = true; - - options.JsonSerializerOptions.Converters.Add(new AbpStringToEnumFactory()); - options.JsonSerializerOptions.Converters.Add(new AbpStringToBooleanConverter()); - - options.JsonSerializerOptions.Converters.Add(new ObjectToInferredTypesConverter()); - - options.JsonSerializerOptions.TypeInfoResolver = new AbpDefaultJsonTypeInfoResolver(ServiceProvider.GetRequiredService>()); - } -} 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 index 39a4e0670a..ea3f5ea156 100644 --- 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 @@ -1,8 +1,11 @@ -using Microsoft.AspNetCore.Mvc; +using System; +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 Volo.Abp.Json.SystemTextJson; +using Volo.Abp.Json.SystemTextJson.JsonConverters; namespace Volo.Abp.AspNetCore.Mvc.Json; @@ -10,8 +13,6 @@ public static class MvcCoreBuilderExtensions { public static IMvcCoreBuilder AddAbpHybridJson(this IMvcCoreBuilder builder) { - builder.Services.TryAddEnumerable(ServiceDescriptor.Transient, AbpJsonOptionsSetup>()); - builder.Services.Configure(options => { options.InputFormatters.RemoveType(); @@ -27,6 +28,20 @@ public static class MvcCoreBuilderExtensions options.TextOutputFormatters.Add(); }); + builder.Services.AddOptions() + .Configure((options, serviceProvider) => + { + options.JsonSerializerOptions.ReadCommentHandling = JsonCommentHandling.Skip; + options.JsonSerializerOptions.AllowTrailingCommas = true; + + options.JsonSerializerOptions.Converters.Add(new AbpStringToEnumFactory()); + options.JsonSerializerOptions.Converters.Add(new AbpStringToBooleanConverter()); + options.JsonSerializerOptions.Converters.Add(new ObjectToInferredTypesConverter()); + + options.JsonSerializerOptions.TypeInfoResolver = new AbpDefaultJsonTypeInfoResolver(serviceProvider + .GetRequiredService>()); + }); + return builder; } } diff --git a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpJsonNewtonsoftModule.cs b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpJsonNewtonsoftModule.cs index e276821bcb..0989dfdd03 100644 --- a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpJsonNewtonsoftModule.cs +++ b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpJsonNewtonsoftModule.cs @@ -1,4 +1,5 @@ -using Volo.Abp.Modularity; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Modularity; using Volo.Abp.Timing; namespace Volo.Abp.Json.Newtonsoft; @@ -12,5 +13,11 @@ public class AbpJsonNewtonsoftModule : AbpModule { options.Providers.Add(); }); + + context.Services.AddOptions() + .Configure((options, contractResolver) => + { + options.JsonSerializerSettings.ContractResolver = contractResolver; + }); } } diff --git a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializerOptions.cs b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializerOptions.cs index d4e392cf80..e5da4ac83f 100644 --- a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializerOptions.cs +++ b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializerOptions.cs @@ -1,14 +1,13 @@ using Newtonsoft.Json; -using Volo.Abp.Collections; namespace Volo.Abp.Json.Newtonsoft; public class AbpNewtonsoftJsonSerializerOptions { - public ITypeList Converters { get; } + public JsonSerializerSettings JsonSerializerSettings { get; } public AbpNewtonsoftJsonSerializerOptions() { - Converters = new TypeList(); + JsonSerializerSettings = new JsonSerializerSettings(); } } diff --git a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializerProvider.cs b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializerProvider.cs index 01c7c1be14..a23580bf6c 100644 --- a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializerProvider.cs +++ b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializerProvider.cs @@ -1,8 +1,6 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; -using System.Linq; -using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Newtonsoft.Json; using Volo.Abp.DependencyInjection; @@ -10,18 +8,11 @@ namespace Volo.Abp.Json.Newtonsoft; public class AbpNewtonsoftJsonSerializerProvider : IJsonSerializerProvider, ITransientDependency { - protected IServiceProvider ServiceProvider{ get; } - protected List Converters { get; } + protected IOptions Options { get; } - public AbpNewtonsoftJsonSerializerProvider( - IServiceProvider serviceProvider, - IOptions options) + public AbpNewtonsoftJsonSerializerProvider(IOptions options) { - ServiceProvider = serviceProvider; - Converters = options.Value - .Converters - .Select(c => (JsonConverter)serviceProvider.GetRequiredService(c)) - .ToList(); + Options = options; } public bool CanHandle(Type type) @@ -46,6 +37,7 @@ public class AbpNewtonsoftJsonSerializerProvider : IJsonSerializerProvider, ITra private readonly static ConcurrentDictionary JsonSerializerOptionsCache = new ConcurrentDictionary(); + protected virtual JsonSerializerSettings CreateJsonSerializerOptions(bool camelCase = true, bool indented = false) { return JsonSerializerOptionsCache.GetOrAdd(new @@ -54,14 +46,45 @@ public class AbpNewtonsoftJsonSerializerProvider : IJsonSerializerProvider, ITra indented }, _ => { - var settings = new JsonSerializerSettings(); + var settings = new JsonSerializerSettings { + Binder = Options.Value.JsonSerializerSettings.Binder, CheckAdditionalContent = Options.Value.JsonSerializerSettings.CheckAdditionalContent, + Context = Options.Value.JsonSerializerSettings.Context, + ContractResolver = Options.Value.JsonSerializerSettings.ContractResolver, + ConstructorHandling = Options.Value.JsonSerializerSettings.ConstructorHandling, + Converters = Options.Value.JsonSerializerSettings.Converters, + Culture = Options.Value.JsonSerializerSettings.Culture, + DateFormatHandling = Options.Value.JsonSerializerSettings.DateFormatHandling, + DateFormatString = Options.Value.JsonSerializerSettings.DateFormatString, + DateParseHandling = Options.Value.JsonSerializerSettings.DateParseHandling, + DateTimeZoneHandling = Options.Value.JsonSerializerSettings.DateTimeZoneHandling, + DefaultValueHandling = Options.Value.JsonSerializerSettings.DefaultValueHandling, + Error = Options.Value.JsonSerializerSettings.Error, + EqualityComparer = Options.Value.JsonSerializerSettings.EqualityComparer, + FloatFormatHandling = Options.Value.JsonSerializerSettings.FloatFormatHandling, + FloatParseHandling = Options.Value.JsonSerializerSettings.FloatParseHandling, + Formatting = Options.Value.JsonSerializerSettings.Formatting, + MaxDepth = Options.Value.JsonSerializerSettings.MaxDepth, + MetadataPropertyHandling = Options.Value.JsonSerializerSettings.MetadataPropertyHandling, + MissingMemberHandling = Options.Value.JsonSerializerSettings.MissingMemberHandling, + NullValueHandling = Options.Value.JsonSerializerSettings.NullValueHandling, + ObjectCreationHandling = Options.Value.JsonSerializerSettings.ObjectCreationHandling, + PreserveReferencesHandling = Options.Value.JsonSerializerSettings.PreserveReferencesHandling, + ReferenceLoopHandling = Options.Value.JsonSerializerSettings.ReferenceLoopHandling, + ReferenceResolver = Options.Value.JsonSerializerSettings.ReferenceResolver, + ReferenceResolverProvider = Options.Value.JsonSerializerSettings.ReferenceResolverProvider, + SerializationBinder = Options.Value.JsonSerializerSettings.SerializationBinder, + StringEscapeHandling = Options.Value.JsonSerializerSettings.StringEscapeHandling, + TraceWriter = Options.Value.JsonSerializerSettings.TraceWriter, + TypeNameAssemblyFormat = Options.Value.JsonSerializerSettings.TypeNameAssemblyFormat, + TypeNameHandling = Options.Value.JsonSerializerSettings.TypeNameHandling, + TypeNameAssemblyFormatHandling = Options.Value.JsonSerializerSettings.TypeNameAssemblyFormatHandling + }; - settings.Converters.InsertRange(0, Converters); - if (camelCase) - { - settings.ContractResolver = ServiceProvider.GetRequiredService(); - } + // if (camelCase) + // { + // settings.ContractResolver = ServiceProvider.GetRequiredService(); + // } if (indented) { diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpJsonSystemTextJsonModule.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpJsonSystemTextJsonModule.cs index ac7e66a7ef..178d0aa6a1 100644 --- a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpJsonSystemTextJsonModule.cs +++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpJsonSystemTextJsonModule.cs @@ -1,6 +1,9 @@ -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.DependencyInjection.Extensions; +using System; +using System.Text.Encodings.Web; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; +using Volo.Abp.Json.SystemTextJson.JsonConverters; +using Volo.Abp.Json.SystemTextJson.Modifiers; using Volo.Abp.Modularity; using Volo.Abp.Timing; @@ -11,12 +14,29 @@ public class AbpJsonSystemTextJsonModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.TryAddEnumerable(ServiceDescriptor.Transient, AbpSystemTextJsonSerializerOptionsSetup>()); - context.Services.TryAddEnumerable(ServiceDescriptor.Transient, AbpSystemTextJsonSerializerModifiersOptionsSetup>()); - Configure(options => { options.Providers.Add(); }); + + context.Services.AddOptions() + .Configure((options, serviceProvider) => + { + // If the user hasn't explicitly configured the encoder, use the less strict encoder that does not encode all non-ASCII characters. + options.JsonSerializerOptions.Encoder ??= JavaScriptEncoder.UnsafeRelaxedJsonEscaping; + + options.JsonSerializerOptions.Converters.Add(new AbpStringToEnumFactory()); + options.JsonSerializerOptions.Converters.Add(new AbpStringToBooleanConverter()); + options.JsonSerializerOptions.Converters.Add(new ObjectToInferredTypesConverter()); + + options.JsonSerializerOptions.TypeInfoResolver = new AbpDefaultJsonTypeInfoResolver(serviceProvider + .GetRequiredService>()); + }); + + context.Services.AddOptions() + .Configure((options, serviceProvider) => + { + options.Modifiers.Add(new AbpDateTimeConverterModifier().CreateModifyAction(serviceProvider)); + }); } } diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerModifiersOptionsSetup.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerModifiersOptionsSetup.cs deleted file mode 100644 index f0ee1e9cfb..0000000000 --- a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerModifiersOptionsSetup.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using Microsoft.Extensions.Options; -using Volo.Abp.Json.SystemTextJson.Modifiers; - -namespace Volo.Abp.Json.SystemTextJson; - -public class AbpSystemTextJsonSerializerModifiersOptionsSetup : IConfigureOptions -{ - protected IServiceProvider ServiceProvider { get; } - - public AbpSystemTextJsonSerializerModifiersOptionsSetup(IServiceProvider serviceProvider) - { - ServiceProvider = serviceProvider; - } - - public void Configure(AbpSystemTextJsonSerializerModifiersOptions options) - { - options.Modifiers.Add(new AbpDateTimeConverterModifier().CreateModifyAction(ServiceProvider)); - } -} diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerOptionsSetup.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerOptionsSetup.cs deleted file mode 100644 index a9a35c1d47..0000000000 --- a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerOptionsSetup.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using System.Text.Encodings.Web; -using System.Text.Json.Serialization; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Options; -using Volo.Abp.Json.SystemTextJson.JsonConverters; - -namespace Volo.Abp.Json.SystemTextJson; - -public class AbpSystemTextJsonSerializerOptionsSetup : IConfigureOptions -{ - protected IServiceProvider ServiceProvider { get; } - - public AbpSystemTextJsonSerializerOptionsSetup(IServiceProvider serviceProvider) - { - ServiceProvider = serviceProvider; - } - - public void Configure(AbpSystemTextJsonSerializerOptions options) - { - options.JsonSerializerOptions.Converters.Add(new AbpStringToEnumFactory()); - options.JsonSerializerOptions.Converters.Add(new AbpStringToBooleanConverter()); - - options.JsonSerializerOptions.Converters.Add(new ObjectToInferredTypesConverter()); - - // If the user hasn't explicitly configured the encoder, use the less strict encoder that does not encode all non-ASCII characters. - options.JsonSerializerOptions.Encoder ??= JavaScriptEncoder.UnsafeRelaxedJsonEscaping; - - options.JsonSerializerOptions.TypeInfoResolver = new AbpDefaultJsonTypeInfoResolver(ServiceProvider.GetRequiredService>()); - } -}