From 03ffe81d831977337565e44511303ff4785cd014 Mon Sep 17 00:00:00 2001 From: maliming Date: Thu, 21 Jul 2022 16:09:09 +0800 Subject: [PATCH 001/124] Split JSON into `Newtonsoft` & `SystemTextJson` packages. Resolve #12124 --- framework/Volo.Abp.sln | 21 +++++++++++++ .../src/Volo.Abp.Json.Core/FodyWeavers.xml | 3 ++ .../src/Volo.Abp.Json.Core/FodyWeavers.xsd | 30 +++++++++++++++++++ .../Volo.Abp.Json.Core.csproj | 20 +++++++++++++ .../Volo/Abp/Json/AbpHybridJsonSerializer.cs | 0 .../Volo/Abp/Json/AbpJsonCoreModule.cs | 8 +++++ .../Volo/Abp/Json/AbpJsonOptions.cs | 2 -- .../Volo/Abp/Json/IJsonSerializer.cs | 0 .../Volo/Abp/Json/IJsonSerializerProvider.cs | 0 .../Volo.Abp.Json.Newtonsoft/FodyWeavers.xml | 3 ++ .../Volo.Abp.Json.Newtonsoft/FodyWeavers.xsd | 30 +++++++++++++++++++ .../Volo.Abp.Json.Newtonsoft.csproj | 23 ++++++++++++++ .../Newtonsoft/AbpJsonIsoDateTimeConverter.cs | 0 .../Newtonsoft/AbpJsonNewtonsoftModule.cs | 21 +++++++++++++ .../AbpNewtonsoftJsonSerializerOptions.cs | 0 .../AbpNewtonsoftJsonSerializerProvider.cs | 0 .../FodyWeavers.xml | 3 ++ .../FodyWeavers.xsd | 30 +++++++++++++++++++ .../Volo.Abp.Json.SystemTextJson.csproj | 22 ++++++++++++++ .../AbpJsonSystemTextJsonModule.cs | 26 ++++++++++++++++ .../AbpSystemTextJsonSerializerOptions.cs | 0 ...AbpSystemTextJsonSerializerOptionsSetup.cs | 0 .../AbpSystemTextJsonSerializerProvider.cs | 0 ...AbpSystemTextJsonUnsupportedTypeMatcher.cs | 0 .../JsonConverters/AbpDateTimeConverter.cs | 4 +-- .../AbpNullableDateTimeConverter.cs | 0 .../AbpStringToBooleanConverter.cs | 0 .../AbpStringToEnumConverter.cs | 0 .../JsonConverters/AbpStringToEnumFactory.cs | 0 .../ObjectToInferredTypesConverter.cs | 0 .../src/Volo.Abp.Json/Volo.Abp.Json.csproj | 5 ++-- .../Volo/Abp/Json/AbpJsonModule.cs | 27 ++--------------- 32 files changed, 246 insertions(+), 32 deletions(-) create mode 100644 framework/src/Volo.Abp.Json.Core/FodyWeavers.xml create mode 100644 framework/src/Volo.Abp.Json.Core/FodyWeavers.xsd create mode 100644 framework/src/Volo.Abp.Json.Core/Volo.Abp.Json.Core.csproj rename framework/src/{Volo.Abp.Json => Volo.Abp.Json.Core}/Volo/Abp/Json/AbpHybridJsonSerializer.cs (100%) create mode 100644 framework/src/Volo.Abp.Json.Core/Volo/Abp/Json/AbpJsonCoreModule.cs rename framework/src/{Volo.Abp.Json => Volo.Abp.Json.Core}/Volo/Abp/Json/AbpJsonOptions.cs (87%) rename framework/src/{Volo.Abp.Json => Volo.Abp.Json.Core}/Volo/Abp/Json/IJsonSerializer.cs (100%) rename framework/src/{Volo.Abp.Json => Volo.Abp.Json.Core}/Volo/Abp/Json/IJsonSerializerProvider.cs (100%) create mode 100644 framework/src/Volo.Abp.Json.Newtonsoft/FodyWeavers.xml create mode 100644 framework/src/Volo.Abp.Json.Newtonsoft/FodyWeavers.xsd create mode 100644 framework/src/Volo.Abp.Json.Newtonsoft/Volo.Abp.Json.Newtonsoft.csproj rename framework/src/{Volo.Abp.Json => Volo.Abp.Json.Newtonsoft}/Volo/Abp/Json/Newtonsoft/AbpJsonIsoDateTimeConverter.cs (100%) create mode 100644 framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpJsonNewtonsoftModule.cs rename framework/src/{Volo.Abp.Json => Volo.Abp.Json.Newtonsoft}/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializerOptions.cs (100%) rename framework/src/{Volo.Abp.Json => Volo.Abp.Json.Newtonsoft}/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializerProvider.cs (100%) create mode 100644 framework/src/Volo.Abp.Json.SystemTextJson/FodyWeavers.xml create mode 100644 framework/src/Volo.Abp.Json.SystemTextJson/FodyWeavers.xsd create mode 100644 framework/src/Volo.Abp.Json.SystemTextJson/Volo.Abp.Json.SystemTextJson.csproj create mode 100644 framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpJsonSystemTextJsonModule.cs rename framework/src/{Volo.Abp.Json => Volo.Abp.Json.SystemTextJson}/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerOptions.cs (100%) rename framework/src/{Volo.Abp.Json => Volo.Abp.Json.SystemTextJson}/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerOptionsSetup.cs (100%) rename framework/src/{Volo.Abp.Json => Volo.Abp.Json.SystemTextJson}/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerProvider.cs (100%) rename framework/src/{Volo.Abp.Json => Volo.Abp.Json.SystemTextJson}/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonUnsupportedTypeMatcher.cs (100%) rename framework/src/{Volo.Abp.Json => Volo.Abp.Json.SystemTextJson}/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpDateTimeConverter.cs (95%) rename framework/src/{Volo.Abp.Json => Volo.Abp.Json.SystemTextJson}/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpNullableDateTimeConverter.cs (100%) rename framework/src/{Volo.Abp.Json => Volo.Abp.Json.SystemTextJson}/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpStringToBooleanConverter.cs (100%) rename framework/src/{Volo.Abp.Json => Volo.Abp.Json.SystemTextJson}/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpStringToEnumConverter.cs (100%) rename framework/src/{Volo.Abp.Json => Volo.Abp.Json.SystemTextJson}/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpStringToEnumFactory.cs (100%) rename framework/src/{Volo.Abp.Json => Volo.Abp.Json.SystemTextJson}/Volo/Abp/Json/SystemTextJson/JsonConverters/ObjectToInferredTypesConverter.cs (100%) diff --git a/framework/Volo.Abp.sln b/framework/Volo.Abp.sln index fadd40bcc5..82f67fe15c 100644 --- a/framework/Volo.Abp.sln +++ b/framework/Volo.Abp.sln @@ -409,6 +409,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.RemoteServices", " EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.AspNetCore.Mvc.PlugIn", "test\Volo.Abp.AspNetCore.Mvc.PlugIn\Volo.Abp.AspNetCore.Mvc.PlugIn.csproj", "{C6D6D878-208A-4FD2-822E-365545D8681B}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Json.Newtonsoft", "src\Volo.Abp.Json.Newtonsoft\Volo.Abp.Json.Newtonsoft.csproj", "{9DD41C8F-0886-483C-B98B-C55EAA7F226D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Json.SystemTextJson", "src\Volo.Abp.Json.SystemTextJson\Volo.Abp.Json.SystemTextJson.csproj", "{0AD06E14-CBFE-4551-8D18-9E921D8F2A87}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Json.Core", "src\Volo.Abp.Json.Core\Volo.Abp.Json.Core.csproj", "{08531C5D-0436-4721-986D-96446CF54316}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -1219,6 +1225,18 @@ Global {C6D6D878-208A-4FD2-822E-365545D8681B}.Debug|Any CPU.Build.0 = Debug|Any CPU {C6D6D878-208A-4FD2-822E-365545D8681B}.Release|Any CPU.ActiveCfg = Release|Any CPU {C6D6D878-208A-4FD2-822E-365545D8681B}.Release|Any CPU.Build.0 = Release|Any CPU + {9DD41C8F-0886-483C-B98B-C55EAA7F226D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9DD41C8F-0886-483C-B98B-C55EAA7F226D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9DD41C8F-0886-483C-B98B-C55EAA7F226D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9DD41C8F-0886-483C-B98B-C55EAA7F226D}.Release|Any CPU.Build.0 = Release|Any CPU + {0AD06E14-CBFE-4551-8D18-9E921D8F2A87}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0AD06E14-CBFE-4551-8D18-9E921D8F2A87}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0AD06E14-CBFE-4551-8D18-9E921D8F2A87}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0AD06E14-CBFE-4551-8D18-9E921D8F2A87}.Release|Any CPU.Build.0 = Release|Any CPU + {08531C5D-0436-4721-986D-96446CF54316}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {08531C5D-0436-4721-986D-96446CF54316}.Debug|Any CPU.Build.0 = Debug|Any CPU + {08531C5D-0436-4721-986D-96446CF54316}.Release|Any CPU.ActiveCfg = Release|Any CPU + {08531C5D-0436-4721-986D-96446CF54316}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1425,6 +1443,9 @@ Global {3683340D-92F5-4B14-B77B-34A163333309} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {EDFFDA74-090D-439C-A58D-06CCF86D4423} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {C6D6D878-208A-4FD2-822E-365545D8681B} = {447C8A77-E5F0-4538-8687-7383196D04EA} + {9DD41C8F-0886-483C-B98B-C55EAA7F226D} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} + {0AD06E14-CBFE-4551-8D18-9E921D8F2A87} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} + {08531C5D-0436-4721-986D-96446CF54316} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {BB97ECF4-9A84-433F-A80B-2A3285BDD1D5} diff --git a/framework/src/Volo.Abp.Json.Core/FodyWeavers.xml b/framework/src/Volo.Abp.Json.Core/FodyWeavers.xml new file mode 100644 index 0000000000..bc5a74a236 --- /dev/null +++ b/framework/src/Volo.Abp.Json.Core/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + diff --git a/framework/src/Volo.Abp.Json.Core/FodyWeavers.xsd b/framework/src/Volo.Abp.Json.Core/FodyWeavers.xsd new file mode 100644 index 0000000000..3f3946e282 --- /dev/null +++ b/framework/src/Volo.Abp.Json.Core/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + '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.Core/Volo.Abp.Json.Core.csproj b/framework/src/Volo.Abp.Json.Core/Volo.Abp.Json.Core.csproj new file mode 100644 index 0000000000..b7a88c22f6 --- /dev/null +++ b/framework/src/Volo.Abp.Json.Core/Volo.Abp.Json.Core.csproj @@ -0,0 +1,20 @@ + + + + + + + netstandard2.0 + Volo.Abp.Json.Core + $(AssetTargetFallback);portable-net45+win8+wp8+wpa81; + false + false + false + + + + + + + + diff --git a/framework/src/Volo.Abp.Json/Volo/Abp/Json/AbpHybridJsonSerializer.cs b/framework/src/Volo.Abp.Json.Core/Volo/Abp/Json/AbpHybridJsonSerializer.cs similarity index 100% rename from framework/src/Volo.Abp.Json/Volo/Abp/Json/AbpHybridJsonSerializer.cs rename to framework/src/Volo.Abp.Json.Core/Volo/Abp/Json/AbpHybridJsonSerializer.cs diff --git a/framework/src/Volo.Abp.Json.Core/Volo/Abp/Json/AbpJsonCoreModule.cs b/framework/src/Volo.Abp.Json.Core/Volo/Abp/Json/AbpJsonCoreModule.cs new file mode 100644 index 0000000000..68de7be35e --- /dev/null +++ b/framework/src/Volo.Abp.Json.Core/Volo/Abp/Json/AbpJsonCoreModule.cs @@ -0,0 +1,8 @@ +using Volo.Abp.Modularity; + +namespace Volo.Abp.Json; + +public class AbpJsonCoreModule : AbpModule +{ + +} diff --git a/framework/src/Volo.Abp.Json/Volo/Abp/Json/AbpJsonOptions.cs b/framework/src/Volo.Abp.Json.Core/Volo/Abp/Json/AbpJsonOptions.cs similarity index 87% rename from framework/src/Volo.Abp.Json/Volo/Abp/Json/AbpJsonOptions.cs rename to framework/src/Volo.Abp.Json.Core/Volo/Abp/Json/AbpJsonOptions.cs index 74d0c0fb6a..73b1d4506d 100644 --- a/framework/src/Volo.Abp.Json/Volo/Abp/Json/AbpJsonOptions.cs +++ b/framework/src/Volo.Abp.Json.Core/Volo/Abp/Json/AbpJsonOptions.cs @@ -1,5 +1,4 @@ using Volo.Abp.Collections; -using Volo.Abp.Json.SystemTextJson; namespace Volo.Abp.Json; @@ -13,7 +12,6 @@ public class AbpJsonOptions /// /// It will try to use System.Json.Text to handle JSON if it can otherwise use Newtonsoft. /// Affects both AbpJsonModule and AbpAspNetCoreMvcModule. - /// See /// public bool UseHybridSerializer { get; set; } diff --git a/framework/src/Volo.Abp.Json/Volo/Abp/Json/IJsonSerializer.cs b/framework/src/Volo.Abp.Json.Core/Volo/Abp/Json/IJsonSerializer.cs similarity index 100% rename from framework/src/Volo.Abp.Json/Volo/Abp/Json/IJsonSerializer.cs rename to framework/src/Volo.Abp.Json.Core/Volo/Abp/Json/IJsonSerializer.cs diff --git a/framework/src/Volo.Abp.Json/Volo/Abp/Json/IJsonSerializerProvider.cs b/framework/src/Volo.Abp.Json.Core/Volo/Abp/Json/IJsonSerializerProvider.cs similarity index 100% rename from framework/src/Volo.Abp.Json/Volo/Abp/Json/IJsonSerializerProvider.cs rename to framework/src/Volo.Abp.Json.Core/Volo/Abp/Json/IJsonSerializerProvider.cs diff --git a/framework/src/Volo.Abp.Json.Newtonsoft/FodyWeavers.xml b/framework/src/Volo.Abp.Json.Newtonsoft/FodyWeavers.xml new file mode 100644 index 0000000000..bc5a74a236 --- /dev/null +++ b/framework/src/Volo.Abp.Json.Newtonsoft/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + diff --git a/framework/src/Volo.Abp.Json.Newtonsoft/FodyWeavers.xsd b/framework/src/Volo.Abp.Json.Newtonsoft/FodyWeavers.xsd new file mode 100644 index 0000000000..3f3946e282 --- /dev/null +++ b/framework/src/Volo.Abp.Json.Newtonsoft/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + '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 new file mode 100644 index 0000000000..d53a9e2b33 --- /dev/null +++ b/framework/src/Volo.Abp.Json.Newtonsoft/Volo.Abp.Json.Newtonsoft.csproj @@ -0,0 +1,23 @@ + + + + + + + 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/Volo/Abp/Json/Newtonsoft/AbpJsonIsoDateTimeConverter.cs b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpJsonIsoDateTimeConverter.cs similarity index 100% rename from framework/src/Volo.Abp.Json/Volo/Abp/Json/Newtonsoft/AbpJsonIsoDateTimeConverter.cs rename to framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpJsonIsoDateTimeConverter.cs 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 new file mode 100644 index 0000000000..afa419bba2 --- /dev/null +++ b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpJsonNewtonsoftModule.cs @@ -0,0 +1,21 @@ +using Volo.Abp.Modularity; +using Volo.Abp.Timing; + +namespace Volo.Abp.Json.Newtonsoft; + +[DependsOn(typeof(AbpJsonCoreModule), typeof(AbpTimingModule))] +public class AbpJsonNewtonsoftModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.Providers.Add(); + }); + + Configure(options => + { + options.Converters.Add(); + }); + } +} diff --git a/framework/src/Volo.Abp.Json/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializerOptions.cs b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializerOptions.cs similarity index 100% rename from framework/src/Volo.Abp.Json/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializerOptions.cs rename to framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializerOptions.cs diff --git a/framework/src/Volo.Abp.Json/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializerProvider.cs b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializerProvider.cs similarity index 100% rename from framework/src/Volo.Abp.Json/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializerProvider.cs rename to framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializerProvider.cs diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/FodyWeavers.xml b/framework/src/Volo.Abp.Json.SystemTextJson/FodyWeavers.xml new file mode 100644 index 0000000000..bc5a74a236 --- /dev/null +++ b/framework/src/Volo.Abp.Json.SystemTextJson/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/FodyWeavers.xsd b/framework/src/Volo.Abp.Json.SystemTextJson/FodyWeavers.xsd new file mode 100644 index 0000000000..3f3946e282 --- /dev/null +++ b/framework/src/Volo.Abp.Json.SystemTextJson/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + '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.SystemTextJson/Volo.Abp.Json.SystemTextJson.csproj b/framework/src/Volo.Abp.Json.SystemTextJson/Volo.Abp.Json.SystemTextJson.csproj new file mode 100644 index 0000000000..c9aa014c82 --- /dev/null +++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo.Abp.Json.SystemTextJson.csproj @@ -0,0 +1,22 @@ + + + + + + + netstandard2.0 + Volo.Abp.Json.SystemTextJson + Volo.Abp.Json.SystemTextJson + $(AssetTargetFallback);portable-net45+win8+wp8+wpa81; + false + false + false + + + + + + + + + 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 new file mode 100644 index 0000000000..4b15408b51 --- /dev/null +++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpJsonSystemTextJsonModule.cs @@ -0,0 +1,26 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Microsoft.Extensions.Options; +using Volo.Abp.Modularity; +using Volo.Abp.Timing; + +namespace Volo.Abp.Json.SystemTextJson; + +[DependsOn(typeof(AbpJsonCoreModule), typeof(AbpTimingModule))] +public class AbpJsonSystemTextJsonModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.TryAddEnumerable(ServiceDescriptor + .Transient, AbpSystemTextJsonSerializerOptionsSetup>()); + + var preActions = context.Services.GetPreConfigureActions(); + Configure(options => + { + if (preActions.Configure().UseHybridSerializer) + { + options.Providers.Add(); + } + }); + } +} diff --git a/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerOptions.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerOptions.cs similarity index 100% rename from framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerOptions.cs rename to framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerOptions.cs diff --git a/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerOptionsSetup.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerOptionsSetup.cs similarity index 100% rename from framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerOptionsSetup.cs rename to framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerOptionsSetup.cs diff --git a/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerProvider.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerProvider.cs similarity index 100% rename from framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerProvider.cs rename to framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerProvider.cs diff --git a/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonUnsupportedTypeMatcher.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonUnsupportedTypeMatcher.cs similarity index 100% rename from framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonUnsupportedTypeMatcher.cs rename to framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonUnsupportedTypeMatcher.cs diff --git a/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpDateTimeConverter.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpDateTimeConverter.cs similarity index 95% rename from framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpDateTimeConverter.cs rename to framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpDateTimeConverter.cs index 42af711772..417037e776 100644 --- a/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpDateTimeConverter.cs +++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpDateTimeConverter.cs @@ -37,9 +37,9 @@ public class AbpDateTimeConverter : JsonConverter, ITransientDependenc throw new JsonException("Reader's TokenType is not String!"); } - if (reader.TryGetDateTime(out var d2)) + if (reader.TryGetDateTime(out var d3)) { - return _clock.Normalize(d2); + return _clock.Normalize(d3); } throw new JsonException("Can't get datetime from the reader!"); diff --git a/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpNullableDateTimeConverter.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpNullableDateTimeConverter.cs similarity index 100% rename from framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpNullableDateTimeConverter.cs rename to framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpNullableDateTimeConverter.cs diff --git a/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpStringToBooleanConverter.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpStringToBooleanConverter.cs similarity index 100% rename from framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpStringToBooleanConverter.cs rename to framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpStringToBooleanConverter.cs diff --git a/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpStringToEnumConverter.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpStringToEnumConverter.cs similarity index 100% rename from framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpStringToEnumConverter.cs rename to framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpStringToEnumConverter.cs diff --git a/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpStringToEnumFactory.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpStringToEnumFactory.cs similarity index 100% rename from framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpStringToEnumFactory.cs rename to framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpStringToEnumFactory.cs diff --git a/framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/ObjectToInferredTypesConverter.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/ObjectToInferredTypesConverter.cs similarity index 100% rename from framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/JsonConverters/ObjectToInferredTypesConverter.cs rename to framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/ObjectToInferredTypesConverter.cs diff --git a/framework/src/Volo.Abp.Json/Volo.Abp.Json.csproj b/framework/src/Volo.Abp.Json/Volo.Abp.Json.csproj index 76cbe9f28f..fd0408acba 100644 --- a/framework/src/Volo.Abp.Json/Volo.Abp.Json.csproj +++ b/framework/src/Volo.Abp.Json/Volo.Abp.Json.csproj @@ -15,9 +15,8 @@ - - - + + 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 77f791cd27..ef9419a784 100644 --- a/framework/src/Volo.Abp.Json/Volo/Abp/Json/AbpJsonModule.cs +++ b/framework/src/Volo.Abp.Json/Volo/Abp/Json/AbpJsonModule.cs @@ -1,34 +1,11 @@ -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.DependencyInjection.Extensions; -using Microsoft.Extensions.Options; -using Volo.Abp.Json.Newtonsoft; +using Volo.Abp.Json.Newtonsoft; using Volo.Abp.Json.SystemTextJson; using Volo.Abp.Modularity; -using Volo.Abp.Timing; namespace Volo.Abp.Json; -[DependsOn(typeof(AbpTimingModule))] +[DependsOn(typeof(AbpJsonNewtonsoftModule), typeof(AbpJsonSystemTextJsonModule))] public class AbpJsonModule : AbpModule { - public override void ConfigureServices(ServiceConfigurationContext context) - { - context.Services.TryAddEnumerable(ServiceDescriptor - .Transient, AbpSystemTextJsonSerializerOptionsSetup>()); - var preActions = context.Services.GetPreConfigureActions(); - Configure(options => - { - options.Providers.Add(); - if (preActions.Configure().UseHybridSerializer) - { - options.Providers.Add(); - } - }); - - Configure(options => - { - options.Converters.Add(); - }); - } } From 27b305d5bd44c83b43e34238151a42dd8ad9968f Mon Sep 17 00:00:00 2001 From: maliming Date: Thu, 21 Jul 2022 16:11:10 +0800 Subject: [PATCH 002/124] Update common.ps1 --- nupkg/common.ps1 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nupkg/common.ps1 b/nupkg/common.ps1 index f13746aed0..b39e3b1ec2 100644 --- a/nupkg/common.ps1 +++ b/nupkg/common.ps1 @@ -191,6 +191,9 @@ $projects = ( "framework/src/Volo.Abp.Http", "framework/src/Volo.Abp.IdentityModel", "framework/src/Volo.Abp.Json", + "framework/src/Volo.Abp.Json.Core", + "framework/src/Volo.Abp.Json.Newtonsoft", + "framework/src/Volo.Abp.Json.SystemTextJson", "framework/src/Volo.Abp.Ldap", "framework/src/Volo.Abp.Localization.Abstractions", "framework/src/Volo.Abp.MailKit", From f77f92aeee54e1f75a8a77cddbd257c0fd594c9b Mon Sep 17 00:00:00 2001 From: maliming Date: Fri, 22 Jul 2022 16:53:59 +0800 Subject: [PATCH 003/124] Add `Volo.Abp.AspNetCore.Mvc.NewtonsoftJson` package. --- framework/Volo.Abp.sln | 7 ++ .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 ++++++++ ...o.Abp.AspNetCore.Mvc.NewtonsoftJson.csproj | 28 ++++++++ .../AbpAspNetCoreMvcNewtonsoftModule.cs | 42 +++++++++++ .../AbpAspNetCoreMvcNewtonsoftOptions.cs | 11 +++ .../AbpMvcNewtonsoftJsonOptionsSetup.cs | 4 +- .../AbpNewtonsoftJsonContractResolver.cs} | 6 +- .../AbpNewtonsoftJsonFormatter.cs | 65 +++++++++++++++++ .../Volo.Abp.AspNetCore.Mvc.csproj | 1 - .../Mvc/Json/AbpHybridJsonFormatterOptions.cs | 17 +++++ .../Mvc/Json/AbpHybridJsonInputFormatter.cs | 31 ++++---- .../Mvc/Json/AbpHybridJsonOptionsSetup.cs | 72 ------------------- .../Mvc/Json/AbpHybridJsonOutputFormatter.cs | 32 ++++----- .../Mvc/Json/AbpSystemTextJsonFormatter.cs | 60 ++++++++++++++++ .../Mvc/Json/IAbpHybridJsonInputFormatter.cs | 12 ++++ .../Mvc/Json/IAbpHybridJsonOutputFormatter.cs | 12 ++++ .../Mvc/Json/MvcCoreBuilderExtensions.cs | 28 ++++---- .../Volo/Abp/Json/AbpJsonOptions.cs | 7 -- .../AbpJsonSystemTextJsonModule.cs | 9 +-- .../Volo.Abp.AspNetCore.Mvc.Tests.csproj | 2 +- .../Mvc/AbpAspNetCoreMvcTestModule.cs | 3 +- nupkg/common.ps1 | 1 + 23 files changed, 345 insertions(+), 138 deletions(-) create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/FodyWeavers.xml create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/FodyWeavers.xsd create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson.csproj create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpAspNetCoreMvcNewtonsoftModule.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpAspNetCoreMvcNewtonsoftOptions.cs rename framework/src/{Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json => Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson}/AbpMvcNewtonsoftJsonOptionsSetup.cs (83%) rename framework/src/{Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpMvcJsonContractResolver.cs => Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpNewtonsoftJsonContractResolver.cs} (85%) create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpNewtonsoftJsonFormatter.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonFormatterOptions.cs delete mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonOptionsSetup.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpSystemTextJsonFormatter.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/IAbpHybridJsonInputFormatter.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/IAbpHybridJsonOutputFormatter.cs diff --git a/framework/Volo.Abp.sln b/framework/Volo.Abp.sln index 82f67fe15c..b646c5f9e6 100644 --- a/framework/Volo.Abp.sln +++ b/framework/Volo.Abp.sln @@ -415,6 +415,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Json.SystemTextJso EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Json.Core", "src\Volo.Abp.Json.Core\Volo.Abp.Json.Core.csproj", "{08531C5D-0436-4721-986D-96446CF54316}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.AspNetCore.Mvc.NewtonsoftJson", "src\Volo.Abp.AspNetCore.Mvc.NewtonsoftJson\Volo.Abp.AspNetCore.Mvc.NewtonsoftJson.csproj", "{0CFC9D4F-F12F-4B44-ABCF-AB4A0E9E85B2}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -1237,6 +1239,10 @@ Global {08531C5D-0436-4721-986D-96446CF54316}.Debug|Any CPU.Build.0 = Debug|Any CPU {08531C5D-0436-4721-986D-96446CF54316}.Release|Any CPU.ActiveCfg = Release|Any CPU {08531C5D-0436-4721-986D-96446CF54316}.Release|Any CPU.Build.0 = Release|Any CPU + {0CFC9D4F-F12F-4B44-ABCF-AB4A0E9E85B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0CFC9D4F-F12F-4B44-ABCF-AB4A0E9E85B2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0CFC9D4F-F12F-4B44-ABCF-AB4A0E9E85B2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0CFC9D4F-F12F-4B44-ABCF-AB4A0E9E85B2}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1446,6 +1452,7 @@ Global {9DD41C8F-0886-483C-B98B-C55EAA7F226D} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {0AD06E14-CBFE-4551-8D18-9E921D8F2A87} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {08531C5D-0436-4721-986D-96446CF54316} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} + {0CFC9D4F-F12F-4B44-ABCF-AB4A0E9E85B2} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {BB97ECF4-9A84-433F-A80B-2A3285BDD1D5} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/FodyWeavers.xml b/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/FodyWeavers.xml new file mode 100644 index 0000000000..bc5a74a236 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/FodyWeavers.xsd b/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/FodyWeavers.xsd new file mode 100644 index 0000000000..3f3946e282 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + '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.AspNetCore.Mvc.NewtonsoftJson/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson.csproj b/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson.csproj new file mode 100644 index 0000000000..9e8b8951e3 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson.csproj @@ -0,0 +1,28 @@ + + + + + + + net6.0 + true + Volo.Abp.AspNetCore.Mvc.NewtonsoftJson + Volo.Abp.AspNetCore.Mvc.NewtonsoftJson + $(AssetTargetFallback);portable-net45+win8+wp8+wpa81; + false + false + false + true + Library + + + + + + + + + + + + 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 new file mode 100644 index 0000000000..ccf25979db --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpAspNetCoreMvcNewtonsoftModule.cs @@ -0,0 +1,42 @@ +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 Volo.Abp.AspNetCore.Mvc.Json; +using Volo.Abp.Modularity; + +namespace Volo.Abp.AspNetCore.Mvc.NewtonsoftJson; + +[DependsOn(typeof(AbpAspNetCoreMvcModule))] +public class AbpAspNetCoreMvcNewtonsoftModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + var options = context.Services.ExecutePreConfiguredActions(); + + if (options.UseHybridSerializer) + { + context.Services.TryAddSingleton(); + + Configure(mvcOptions => + { + mvcOptions.InputFormatters.RemoveType(); + mvcOptions.OutputFormatters.RemoveType(); + }); + + Configure(formatterOptions => + { + formatterOptions.TextInputFormatters.Add(); + formatterOptions.TextOutputFormatters.Add(); + }); + } + else + { + context.Services.AddMvcCore().AddNewtonsoftJson(); + } + + context.Services.TryAddEnumerable(ServiceDescriptor.Transient, AbpMvcNewtonsoftJsonOptionsSetup>()); + } +} 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 new file mode 100644 index 0000000000..63d11b00b7 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpAspNetCoreMvcNewtonsoftOptions.cs @@ -0,0 +1,11 @@ +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/Volo/Abp/AspNetCore/Mvc/Json/AbpMvcNewtonsoftJsonOptionsSetup.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpMvcNewtonsoftJsonOptionsSetup.cs similarity index 83% rename from framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpMvcNewtonsoftJsonOptionsSetup.cs rename to framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpMvcNewtonsoftJsonOptionsSetup.cs index c68b912372..1d1dc6a373 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpMvcNewtonsoftJsonOptionsSetup.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpMvcNewtonsoftJsonOptionsSetup.cs @@ -3,7 +3,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; -namespace Volo.Abp.AspNetCore.Mvc.Json; +namespace Volo.Abp.AspNetCore.Mvc.NewtonsoftJson; public class AbpMvcNewtonsoftJsonOptionsSetup : IConfigureOptions { @@ -16,6 +16,6 @@ public class AbpMvcNewtonsoftJsonOptionsSetup : IConfigureOptions(); + options.SerializerSettings.ContractResolver = ServiceProvider.GetRequiredService(); } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpMvcJsonContractResolver.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpNewtonsoftJsonContractResolver.cs similarity index 85% rename from framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpMvcJsonContractResolver.cs rename to framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpNewtonsoftJsonContractResolver.cs index a6f242d59c..f33c9abbd4 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpMvcJsonContractResolver.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpNewtonsoftJsonContractResolver.cs @@ -8,13 +8,13 @@ using Volo.Abp.Json.Newtonsoft; using Volo.Abp.Reflection; using Volo.Abp.Timing; -namespace Volo.Abp.AspNetCore.Mvc.Json; +namespace Volo.Abp.AspNetCore.Mvc.NewtonsoftJson; -public class AbpMvcJsonContractResolver : DefaultContractResolver, ITransientDependency +public class AbpNewtonsoftJsonContractResolver : DefaultContractResolver, ITransientDependency { private readonly Lazy _dateTimeConverter; - public AbpMvcJsonContractResolver(IServiceProvider serviceProvider) + public AbpNewtonsoftJsonContractResolver(IServiceProvider serviceProvider) { _dateTimeConverter = new Lazy( serviceProvider.GetRequiredService, diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpNewtonsoftJsonFormatter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpNewtonsoftJsonFormatter.cs new file mode 100644 index 0000000000..aa411bfb61 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpNewtonsoftJsonFormatter.cs @@ -0,0 +1,65 @@ +using System; +using System.Buffers; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Formatters; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.ObjectPool; +using Microsoft.Extensions.Options; +using Volo.Abp.AspNetCore.Mvc.Json; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.AspNetCore.Mvc.NewtonsoftJson; + +public class AbpNewtonsoftJsonFormatter : IAbpHybridJsonInputFormatter, IAbpHybridJsonOutputFormatter, ITransientDependency +{ + private readonly ILoggerFactory _loggerFactory; + private readonly ArrayPool _charPool; + private readonly ObjectPoolProvider _objectPoolProvider; + private readonly IOptions _mvcOptions; + private readonly IOptions _mvcNewtonsoftJsonOptions; + + public AbpNewtonsoftJsonFormatter( + ILoggerFactory loggerFactory, + ArrayPool charPool, + ObjectPoolProvider objectPoolProvider, + IOptions mvcOptions, + IOptions mvcNewtonsoftJsonOptions) + { + _loggerFactory = loggerFactory; + _charPool = charPool; + _objectPoolProvider = objectPoolProvider; + _mvcOptions = mvcOptions; + _mvcNewtonsoftJsonOptions = mvcNewtonsoftJsonOptions; + } + + Task IAbpHybridJsonInputFormatter.CanHandleAsync(Type type) + { + return Task.FromResult(true); + } + + public Task GetTextInputFormatterAsync() + { + return Task.FromResult(new NewtonsoftJsonInputFormatter( + _loggerFactory.CreateLogger(), + _mvcNewtonsoftJsonOptions.Value.SerializerSettings, + _charPool, + _objectPoolProvider, + _mvcOptions.Value, + _mvcNewtonsoftJsonOptions.Value)); + } + + Task IAbpHybridJsonOutputFormatter.CanHandleAsync(Type type) + { + return Task.FromResult(true); + } + + public Task GetTextOutputFormatterAsync() + { + return Task.FromResult(new NewtonsoftJsonOutputFormatter( + _mvcNewtonsoftJsonOptions.Value.SerializerSettings, + _charPool, + _mvcOptions.Value, + _mvcNewtonsoftJsonOptions.Value)); + } +} 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 9113c4529e..048c2308e7 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 @@ -29,7 +29,6 @@ - diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonFormatterOptions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonFormatterOptions.cs new file mode 100644 index 0000000000..066ebe4413 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonFormatterOptions.cs @@ -0,0 +1,17 @@ +using Microsoft.AspNetCore.Mvc.Formatters; +using Volo.Abp.Collections; + +namespace Volo.Abp.AspNetCore.Mvc.Json; + +public class AbpHybridJsonFormatterOptions +{ + public ITypeList TextInputFormatters { get; } + + public ITypeList TextOutputFormatters { get; } + + public AbpHybridJsonFormatterOptions() + { + TextInputFormatters = new TypeList(); + TextOutputFormatters = new TypeList(); + } +} 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 index 69da26a317..874508ac1f 100644 --- 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 @@ -1,21 +1,16 @@ -using System.Text; +using System; +using System.Text; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.Formatters; using Microsoft.Extensions.DependencyInjection; -using Volo.Abp.Json.SystemTextJson; +using Microsoft.Extensions.Options; namespace Volo.Abp.AspNetCore.Mvc.Json; public class AbpHybridJsonInputFormatter : TextInputFormatter, IInputFormatterExceptionPolicy { - private readonly SystemTextJsonInputFormatter _systemTextJsonInputFormatter; - private readonly NewtonsoftJsonInputFormatter _newtonsoftJsonInputFormatter; - - public AbpHybridJsonInputFormatter(SystemTextJsonInputFormatter systemTextJsonInputFormatter, NewtonsoftJsonInputFormatter newtonsoftJsonInputFormatter) + public AbpHybridJsonInputFormatter() { - _systemTextJsonInputFormatter = systemTextJsonInputFormatter; - _newtonsoftJsonInputFormatter = newtonsoftJsonInputFormatter; - SupportedEncodings.Add(UTF8EncodingWithoutBOM); SupportedEncodings.Add(UTF16EncodingLittleEndian); @@ -24,21 +19,25 @@ public class AbpHybridJsonInputFormatter : TextInputFormatter, IInputFormatterEx SupportedMediaTypes.Add(MediaTypeHeaderValues.ApplicationAnyJsonSyntax); } - public override async Task ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding) + public async override Task ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding) { - return await GetTextInputFormatter(context).ReadRequestBodyAsync(context, encoding); + return await (await GetTextInputFormatterAsync(context)).ReadRequestBodyAsync(context, encoding); } - protected virtual TextInputFormatter GetTextInputFormatter(InputFormatterContext context) + protected virtual async Task GetTextInputFormatterAsync(InputFormatterContext context) { - var typesMatcher = context.HttpContext.RequestServices.GetRequiredService(); + var options = context.HttpContext.RequestServices.GetRequiredService>().Value; - if (!typesMatcher.Match(context.ModelType)) + foreach (var inputFormatterType in options.TextInputFormatters) { - return _systemTextJsonInputFormatter; + var inputFormatter = context.HttpContext.RequestServices.GetRequiredService(inputFormatterType).As(); + if (await inputFormatter.CanHandleAsync(context.ModelType)) + { + return await inputFormatter.GetTextInputFormatterAsync(); + } } - return _newtonsoftJsonInputFormatter; + throw new AbpException($"The {nameof(AbpHybridJsonInputFormatter)} can't handle '{context.ModelType.GetFullNameWithAssemblyName()}'!"); } public virtual InputFormatterExceptionPolicy ExceptionPolicy => InputFormatterExceptionPolicy.MalformedInputExceptions; diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonOptionsSetup.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonOptionsSetup.cs deleted file mode 100644 index 794bc79af9..0000000000 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonOptionsSetup.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System.Buffers; -using System.Text.Encodings.Web; -using System.Text.Json; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.Formatters; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.ObjectPool; -using Microsoft.Extensions.Options; - -namespace Volo.Abp.AspNetCore.Mvc.Json; - -public class AbpHybridJsonOptionsSetup : IConfigureOptions -{ - private readonly IOptions _jsonOptions; - private readonly IOptions _mvcNewtonsoftJsonOptions; - private readonly ILoggerFactory _loggerFactory; - private readonly ArrayPool _charPool; - private readonly ObjectPoolProvider _objectPoolProvider; - - public AbpHybridJsonOptionsSetup( - IOptions jsonOptions, - IOptions mvcNewtonsoftJsonOptions, - ILoggerFactory loggerFactory, - ArrayPool charPool, - ObjectPoolProvider objectPoolProvider) - { - _jsonOptions = jsonOptions; - _mvcNewtonsoftJsonOptions = mvcNewtonsoftJsonOptions; - _loggerFactory = loggerFactory; - _charPool = charPool; - _objectPoolProvider = objectPoolProvider; - } - - public void Configure(MvcOptions options) - { - var systemTextJsonInputFormatter = new SystemTextJsonInputFormatter( - _jsonOptions.Value, - _loggerFactory.CreateLogger()); - - var newtonsoftJsonInputFormatter = new NewtonsoftJsonInputFormatter( - _loggerFactory.CreateLogger(), - _mvcNewtonsoftJsonOptions.Value.SerializerSettings, - _charPool, - _objectPoolProvider, - options, - _mvcNewtonsoftJsonOptions.Value); - - options.InputFormatters.RemoveType(); - options.InputFormatters.RemoveType(); - options.InputFormatters.Add(new AbpHybridJsonInputFormatter(systemTextJsonInputFormatter, newtonsoftJsonInputFormatter)); - - var jsonSerializerOptions = _jsonOptions.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, - }; - } - - var systemTextJsonOutputFormatter = new SystemTextJsonOutputFormatter(jsonSerializerOptions); - var newtonsoftJsonOutputFormatter = new NewtonsoftJsonOutputFormatter( - _mvcNewtonsoftJsonOptions.Value.SerializerSettings, - _charPool, - options); - - options.OutputFormatters.RemoveType(); - options.OutputFormatters.RemoveType(); - options.OutputFormatters.Add(new AbpHybridJsonOutputFormatter(systemTextJsonOutputFormatter, newtonsoftJsonOutputFormatter)); - } -} 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 index f4c5df1dc9..2960ff1635 100644 --- 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 @@ -1,21 +1,16 @@ -using System.Text; +using System; +using System.Text; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.Formatters; using Microsoft.Extensions.DependencyInjection; -using Volo.Abp.Json.SystemTextJson; +using Microsoft.Extensions.Options; namespace Volo.Abp.AspNetCore.Mvc.Json; public class AbpHybridJsonOutputFormatter : TextOutputFormatter { - private readonly SystemTextJsonOutputFormatter _systemTextJsonOutputFormatter; - private readonly NewtonsoftJsonOutputFormatter _newtonsoftJsonOutputFormatter; - - public AbpHybridJsonOutputFormatter(SystemTextJsonOutputFormatter systemTextJsonOutputFormatter, NewtonsoftJsonOutputFormatter newtonsoftJsonOutputFormatter) + public AbpHybridJsonOutputFormatter() { - _systemTextJsonOutputFormatter = systemTextJsonOutputFormatter; - _newtonsoftJsonOutputFormatter = newtonsoftJsonOutputFormatter; - SupportedEncodings.Add(Encoding.UTF8); SupportedEncodings.Add(Encoding.Unicode); @@ -24,19 +19,24 @@ public class AbpHybridJsonOutputFormatter : TextOutputFormatter SupportedMediaTypes.Add(MediaTypeHeaderValues.ApplicationAnyJsonSyntax); } - public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding) + public async override Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding) { - await GetTextInputFormatter(context).WriteResponseBodyAsync(context, selectedEncoding); + await (await GetTextInputFormatter(context)).WriteResponseBodyAsync(context, selectedEncoding); } - protected virtual TextOutputFormatter GetTextInputFormatter(OutputFormatterWriteContext context) + protected virtual async Task GetTextInputFormatter(OutputFormatterWriteContext context) { - var typesMatcher = context.HttpContext.RequestServices.GetRequiredService(); - if (!typesMatcher.Match(context.ObjectType)) + var options = context.HttpContext.RequestServices.GetRequiredService>().Value; + + foreach (var outputFormatterType in options.TextOutputFormatters) { - return _systemTextJsonOutputFormatter; + var outputFormatter = context.HttpContext.RequestServices.GetRequiredService(outputFormatterType).As(); + if (await outputFormatter.CanHandleAsync(context.ObjectType)) + { + return await outputFormatter.GetTextOutputFormatterAsync(); + } } - return _newtonsoftJsonOutputFormatter; + throw new AbpException($"The {nameof(AbpHybridJsonOutputFormatter)} can't handle '{context.ObjectType.GetFullNameWithAssemblyName()}'!"); } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpSystemTextJsonFormatter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpSystemTextJsonFormatter.cs new file mode 100644 index 0000000000..e680d54fa5 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpSystemTextJsonFormatter.cs @@ -0,0 +1,60 @@ +using System; +using System.Text.Encodings.Web; +using System.Text.Json; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Formatters; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Json.SystemTextJson; + +namespace Volo.Abp.AspNetCore.Mvc.Json; + +public class AbpSystemTextJsonFormatter : IAbpHybridJsonInputFormatter, IAbpHybridJsonOutputFormatter, ITransientDependency +{ + private readonly AbpSystemTextJsonUnsupportedTypeMatcher _unsupportedTypeMatcher; + private readonly IOptions _jsonOptions; + private readonly ILoggerFactory _loggerFactory; + + public AbpSystemTextJsonFormatter(AbpSystemTextJsonUnsupportedTypeMatcher unsupportedTypeMatcher, + IOptions jsonOptions, + ILoggerFactory loggerFactory) + { + _unsupportedTypeMatcher = unsupportedTypeMatcher; + _jsonOptions = jsonOptions; + _loggerFactory = loggerFactory; + } + + Task IAbpHybridJsonInputFormatter.CanHandleAsync(Type type) + { + return Task.FromResult(!_unsupportedTypeMatcher.Match(type)); + } + + public virtual Task GetTextInputFormatterAsync() + { + return Task.FromResult(new SystemTextJsonInputFormatter( + _jsonOptions.Value, + _loggerFactory.CreateLogger())); + } + + Task IAbpHybridJsonOutputFormatter.CanHandleAsync(Type type) + { + return Task.FromResult(!_unsupportedTypeMatcher.Match(type)); + } + + public Task GetTextOutputFormatterAsync() + { + var jsonSerializerOptions = _jsonOptions.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 Task.FromResult(new SystemTextJsonOutputFormatter(jsonSerializerOptions)); + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/IAbpHybridJsonInputFormatter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/IAbpHybridJsonInputFormatter.cs new file mode 100644 index 0000000000..0a167e58d4 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/IAbpHybridJsonInputFormatter.cs @@ -0,0 +1,12 @@ +using System; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.Formatters; + +namespace Volo.Abp.AspNetCore.Mvc.Json; + +public interface IAbpHybridJsonInputFormatter +{ + Task CanHandleAsync(Type type); + + Task GetTextInputFormatterAsync(); +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/IAbpHybridJsonOutputFormatter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/IAbpHybridJsonOutputFormatter.cs new file mode 100644 index 0000000000..06418b88d4 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/IAbpHybridJsonOutputFormatter.cs @@ -0,0 +1,12 @@ +using System; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.Formatters; + +namespace Volo.Abp.AspNetCore.Mvc.Json; + +public interface IAbpHybridJsonOutputFormatter +{ + Task CanHandleAsync(Type type); + + Task GetTextOutputFormatterAsync(); +} 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 2d3a834d09..39a4e0670a 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,9 +1,8 @@ using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Formatters; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Options; -using Microsoft.Extensions.ObjectPool; -using Volo.Abp.Json; namespace Volo.Abp.AspNetCore.Mvc.Json; @@ -11,18 +10,23 @@ public static class MvcCoreBuilderExtensions { public static IMvcCoreBuilder AddAbpHybridJson(this IMvcCoreBuilder builder) { - var abpJsonOptions = builder.Services.ExecutePreConfiguredActions(); - if (!abpJsonOptions.UseHybridSerializer) + builder.Services.TryAddEnumerable(ServiceDescriptor.Transient, AbpJsonOptionsSetup>()); + + builder.Services.Configure(options => { - builder.Services.TryAddEnumerable(ServiceDescriptor.Transient, AbpMvcNewtonsoftJsonOptionsSetup>()); - builder.AddNewtonsoftJson(); - return builder; - } + options.InputFormatters.RemoveType(); + options.InputFormatters.Add(new AbpHybridJsonInputFormatter()); + + options.OutputFormatters.RemoveType(); + options.OutputFormatters.Add(new AbpHybridJsonOutputFormatter()); + }); + + builder.Services.Configure(options => + { + options.TextInputFormatters.Add(); + options.TextOutputFormatters.Add(); + }); - builder.Services.TryAddTransient(); - builder.Services.TryAddEnumerable(ServiceDescriptor.Transient, AbpJsonOptionsSetup>()); - builder.Services.TryAddEnumerable(ServiceDescriptor.Transient, AbpMvcNewtonsoftJsonOptionsSetup>()); - builder.Services.TryAddEnumerable(ServiceDescriptor.Transient, AbpHybridJsonOptionsSetup>()); return builder; } } diff --git a/framework/src/Volo.Abp.Json.Core/Volo/Abp/Json/AbpJsonOptions.cs b/framework/src/Volo.Abp.Json.Core/Volo/Abp/Json/AbpJsonOptions.cs index 73b1d4506d..ffbd510b93 100644 --- a/framework/src/Volo.Abp.Json.Core/Volo/Abp/Json/AbpJsonOptions.cs +++ b/framework/src/Volo.Abp.Json.Core/Volo/Abp/Json/AbpJsonOptions.cs @@ -9,17 +9,10 @@ public class AbpJsonOptions /// public string DefaultDateTimeFormat { get; set; } - /// - /// It will try to use System.Json.Text to handle JSON if it can otherwise use Newtonsoft. - /// Affects both AbpJsonModule and AbpAspNetCoreMvcModule. - /// - public bool UseHybridSerializer { get; set; } - public ITypeList Providers { get; } public AbpJsonOptions() { Providers = new TypeList(); - UseHybridSerializer = true; } } 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 4b15408b51..895c9bcfe4 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 @@ -11,16 +11,11 @@ public class AbpJsonSystemTextJsonModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.TryAddEnumerable(ServiceDescriptor - .Transient, AbpSystemTextJsonSerializerOptionsSetup>()); + context.Services.TryAddEnumerable(ServiceDescriptor.Transient, AbpSystemTextJsonSerializerOptionsSetup>()); - var preActions = context.Services.GetPreConfigureActions(); Configure(options => { - if (preActions.Configure().UseHybridSerializer) - { - options.Providers.Add(); - } + options.Providers.Add(); }); } } diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo.Abp.AspNetCore.Mvc.Tests.csproj b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo.Abp.AspNetCore.Mvc.Tests.csproj index 53a9bd3747..f577746665 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo.Abp.AspNetCore.Mvc.Tests.csproj +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo.Abp.AspNetCore.Mvc.Tests.csproj @@ -25,7 +25,7 @@ - + diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs index e303a0fb5d..76a95a09cf 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs @@ -11,6 +11,7 @@ using Volo.Abp.AspNetCore.Mvc.Authorization; using Volo.Abp.AspNetCore.Mvc.GlobalFeatures; using Volo.Abp.AspNetCore.Mvc.Localization; using Volo.Abp.AspNetCore.Mvc.Localization.Resource; +using Volo.Abp.AspNetCore.Mvc.NewtonsoftJson; using Volo.Abp.AspNetCore.Security.Claims; using Volo.Abp.AspNetCore.TestBase; using Volo.Abp.Authorization; @@ -29,7 +30,7 @@ namespace Volo.Abp.AspNetCore.Mvc; [DependsOn( typeof(AbpAspNetCoreTestBaseModule), typeof(AbpMemoryDbTestModule), - typeof(AbpAspNetCoreMvcModule), + typeof(AbpAspNetCoreMvcNewtonsoftModule), typeof(AbpAutofacModule) )] public class AbpAspNetCoreMvcTestModule : AbpModule diff --git a/nupkg/common.ps1 b/nupkg/common.ps1 index b39e3b1ec2..9f44b11c6d 100644 --- a/nupkg/common.ps1 +++ b/nupkg/common.ps1 @@ -112,6 +112,7 @@ $projects = ( "framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common", "framework/src/Volo.Abp.AspNetCore.Mvc.Contracts", "framework/src/Volo.Abp.AspNetCore.Mvc", + "framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson", "framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap", "framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling.Abstractions", "framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling", From 4c6eaf8e89390844e9131719ec9224bd88771740 Mon Sep 17 00:00:00 2001 From: maliming Date: Fri, 22 Jul 2022 17:10:57 +0800 Subject: [PATCH 004/124] Update `StringValueJsonConverter_Tests`. --- .../NewtonsoftStringValueJsonConverter_Tests.cs | 3 ++- .../SystemTextJsonStringValueJsonConverter_Tests.cs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/NewtonsoftStringValueJsonConverter_Tests.cs b/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/NewtonsoftStringValueJsonConverter_Tests.cs index 09f3c2266d..4a8a1a36be 100644 --- a/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/NewtonsoftStringValueJsonConverter_Tests.cs +++ b/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/NewtonsoftStringValueJsonConverter_Tests.cs @@ -1,5 +1,6 @@ using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Json; +using Volo.Abp.Json.SystemTextJson; namespace Volo.Abp.FeatureManagement; @@ -9,7 +10,7 @@ public class NewtonsoftStringValueJsonConverter_Tests : StringValueJsonConverter { services.PreConfigure(options => { - options.UseHybridSerializer = false; + options.Providers.Remove(); }); } } diff --git a/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/SystemTextJsonStringValueJsonConverter_Tests.cs b/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/SystemTextJsonStringValueJsonConverter_Tests.cs index 968055c09f..e51f9885ac 100644 --- a/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/SystemTextJsonStringValueJsonConverter_Tests.cs +++ b/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/SystemTextJsonStringValueJsonConverter_Tests.cs @@ -1,5 +1,6 @@ using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Json; +using Volo.Abp.Json.Newtonsoft; namespace Volo.Abp.FeatureManagement; @@ -9,7 +10,7 @@ public class SystemTextJsonStringValueJsonConverter_Tests : StringValueJsonConve { services.PreConfigure(options => { - options.UseHybridSerializer = true; + options.Providers.Remove(); }); } } From 149e5c603b5ae5d5842a774334b32e6096ac5293 Mon Sep 17 00:00:00 2001 From: maliming Date: Fri, 12 Aug 2022 15:23:47 +0800 Subject: [PATCH 005/124] Update Volo.Abp.AspNetCore.Mvc.NewtonsoftJson.csproj --- .../Volo.Abp.AspNetCore.Mvc.NewtonsoftJson.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson.csproj b/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson.csproj index 9e8b8951e3..83ac5bc666 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson.csproj +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson.csproj @@ -4,7 +4,7 @@ - net6.0 + net7.0 true Volo.Abp.AspNetCore.Mvc.NewtonsoftJson Volo.Abp.AspNetCore.Mvc.NewtonsoftJson From 1e9c0871a3dfb53a553e72c38d24ed6d9b23394a Mon Sep 17 00:00:00 2001 From: maliming Date: Tue, 16 Aug 2022 16:21:17 +0800 Subject: [PATCH 006/124] Introduce `IncludeNonPublicPropertiesModifiers`. --- .../AbpMvcNewtonsoftJsonOptionsSetup.cs | 16 ++++- .../Mvc/Json/AbpJsonOptionsSetup.cs | 3 + .../Mvc/Json/AbpSystemTextJsonFormatter.cs | 11 ++-- ...CamelCasePropertyNamesContractResolver.cs} | 19 ++++-- .../AbpNewtonsoftJsonSerializerProvider.cs | 59 ++++++++--------- .../Volo.Abp.Json.SystemTextJson.csproj | 1 + .../AbpDefaultJsonTypeInfoResolver.cs | 16 +++++ ...ystemTextJsonSerializerModifiersOptions.cs | 21 ++++++ ...AbpSystemTextJsonSerializerOptionsSetup.cs | 2 + .../AbpSystemTextJsonSerializerProvider.cs | 9 +-- ...AbpSystemTextJsonUnsupportedTypeMatcher.cs | 21 ------ .../IncludeNonPublicPropertiesModifiers.cs | 37 +++++++++++ .../Abp/ObjectExtending/ExtensibleObject.cs | 2 - ...temTextJsonUnsupportedTypeMatcher_Tests.cs | 65 ------------------- .../Json/ExtensibleObjectModifiers_Tests.cs | 19 ++++++ 15 files changed, 161 insertions(+), 140 deletions(-) rename framework/src/{Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpNewtonsoftJsonContractResolver.cs => Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpCamelCasePropertyNamesContractResolver.cs} (65%) create mode 100644 framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpDefaultJsonTypeInfoResolver.cs create mode 100644 framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerModifiersOptions.cs delete mode 100644 framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonUnsupportedTypeMatcher.cs create mode 100644 framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/IncludeNonPublicPropertiesModifiers.cs delete mode 100644 framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpSystemTextJsonUnsupportedTypeMatcher_Tests.cs create mode 100644 framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/ExtensibleObjectModifiers_Tests.cs 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 index 1d1dc6a373..ab7eaf2244 100644 --- 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 @@ -1,21 +1,31 @@ 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 { - protected IServiceProvider ServiceProvider { get; } + private readonly IServiceProvider _serviceProvider; public AbpMvcNewtonsoftJsonOptionsSetup(IServiceProvider serviceProvider) { - ServiceProvider = serviceProvider; + _serviceProvider = serviceProvider; } public void Configure(MvcNewtonsoftJsonOptions options) { - options.SerializerSettings.ContractResolver = ServiceProvider.GetRequiredService(); + 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 index 116adca4e8..650d3890c1 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 @@ -4,6 +4,7 @@ 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; @@ -29,5 +30,7 @@ public class AbpJsonOptionsSetup : IConfigureOptions 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/AbpSystemTextJsonFormatter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpSystemTextJsonFormatter.cs index e680d54fa5..fb8c509748 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpSystemTextJsonFormatter.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpSystemTextJsonFormatter.cs @@ -13,22 +13,23 @@ namespace Volo.Abp.AspNetCore.Mvc.Json; public class AbpSystemTextJsonFormatter : IAbpHybridJsonInputFormatter, IAbpHybridJsonOutputFormatter, ITransientDependency { - private readonly AbpSystemTextJsonUnsupportedTypeMatcher _unsupportedTypeMatcher; private readonly IOptions _jsonOptions; + private readonly IOptions _systemTextJsonSerializerOptions; private readonly ILoggerFactory _loggerFactory; - public AbpSystemTextJsonFormatter(AbpSystemTextJsonUnsupportedTypeMatcher unsupportedTypeMatcher, + public AbpSystemTextJsonFormatter( IOptions jsonOptions, + IOptions systemTextJsonSerializerOptions, ILoggerFactory loggerFactory) { - _unsupportedTypeMatcher = unsupportedTypeMatcher; _jsonOptions = jsonOptions; + _systemTextJsonSerializerOptions = systemTextJsonSerializerOptions; _loggerFactory = loggerFactory; } Task IAbpHybridJsonInputFormatter.CanHandleAsync(Type type) { - return Task.FromResult(!_unsupportedTypeMatcher.Match(type)); + return Task.FromResult(!_systemTextJsonSerializerOptions.Value.UnsupportedTypes.Contains(type)); } public virtual Task GetTextInputFormatterAsync() @@ -40,7 +41,7 @@ public class AbpSystemTextJsonFormatter : IAbpHybridJsonInputFormatter, IAbpHybr Task IAbpHybridJsonOutputFormatter.CanHandleAsync(Type type) { - return Task.FromResult(!_unsupportedTypeMatcher.Match(type)); + return Task.FromResult(!_systemTextJsonSerializerOptions.Value.UnsupportedTypes.Contains(type)); } public Task GetTextOutputFormatterAsync() diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpNewtonsoftJsonContractResolver.cs b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpCamelCasePropertyNamesContractResolver.cs similarity index 65% rename from framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpNewtonsoftJsonContractResolver.cs rename to framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpCamelCasePropertyNamesContractResolver.cs index f33c9abbd4..502265db84 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpNewtonsoftJsonContractResolver.cs +++ b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpCamelCasePropertyNamesContractResolver.cs @@ -4,17 +4,16 @@ using Microsoft.Extensions.DependencyInjection; 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.NewtonsoftJson; +namespace Volo.Abp.Json.Newtonsoft; -public class AbpNewtonsoftJsonContractResolver : DefaultContractResolver, ITransientDependency +public class AbpCamelCasePropertyNamesContractResolver : CamelCasePropertyNamesContractResolver, ITransientDependency { private readonly Lazy _dateTimeConverter; - public AbpNewtonsoftJsonContractResolver(IServiceProvider serviceProvider) + public AbpCamelCasePropertyNamesContractResolver(IServiceProvider serviceProvider) { _dateTimeConverter = new Lazy( serviceProvider.GetRequiredService, @@ -35,7 +34,8 @@ public class AbpNewtonsoftJsonContractResolver : DefaultContractResolver, ITrans protected virtual void ModifyProperty(MemberInfo member, JsonProperty property) { - if (property.PropertyType != typeof(DateTime) && property.PropertyType != typeof(DateTime?)) + if (property.PropertyType != typeof(DateTime) && + property.PropertyType != typeof(DateTime?)) { return; } @@ -45,4 +45,13 @@ public class AbpNewtonsoftJsonContractResolver : DefaultContractResolver, ITrans property.Converter = _dateTimeConverter.Value; } } + + protected override JsonDictionaryContract CreateDictionaryContract(Type objectType) + { + var contract = base.CreateDictionaryContract(objectType); + + contract.DictionaryKeyResolver = propertyName => propertyName; + + return contract; + } } 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 14ae0556f3..01c7c1be14 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,25 +1,23 @@ 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 Newtonsoft.Json.Serialization; using Volo.Abp.DependencyInjection; - namespace Volo.Abp.Json.Newtonsoft; public class AbpNewtonsoftJsonSerializerProvider : IJsonSerializerProvider, ITransientDependency { - private static readonly CamelCaseExceptDictionaryKeysResolver SharedCamelCaseExceptDictionaryKeysResolver = - new CamelCaseExceptDictionaryKeysResolver(); - + protected IServiceProvider ServiceProvider{ get; } protected List Converters { get; } public AbpNewtonsoftJsonSerializerProvider( - IOptions options, - IServiceProvider serviceProvider) + IServiceProvider serviceProvider, + IOptions options) { + ServiceProvider = serviceProvider; Converters = options.Value .Converters .Select(c => (JsonConverter)serviceProvider.GetRequiredService(c)) @@ -33,47 +31,44 @@ public class AbpNewtonsoftJsonSerializerProvider : IJsonSerializerProvider, ITra public string Serialize(object obj, bool camelCase = true, bool indented = false) { - return JsonConvert.SerializeObject(obj, CreateSerializerSettings(camelCase, indented)); + return JsonConvert.SerializeObject(obj, CreateJsonSerializerOptions(camelCase, indented)); } public T Deserialize(string jsonString, bool camelCase = true) { - return JsonConvert.DeserializeObject(jsonString, CreateSerializerSettings(camelCase)); + return JsonConvert.DeserializeObject(jsonString, CreateJsonSerializerOptions(camelCase)); } public object Deserialize(Type type, string jsonString, bool camelCase = true) { - return JsonConvert.DeserializeObject(jsonString, type, CreateSerializerSettings(camelCase)); + return JsonConvert.DeserializeObject(jsonString, type, CreateJsonSerializerOptions(camelCase)); } - protected virtual JsonSerializerSettings CreateSerializerSettings(bool camelCase = true, bool indented = false) - { - var settings = new JsonSerializerSettings(); + private readonly static ConcurrentDictionary JsonSerializerOptionsCache = new ConcurrentDictionary(); - settings.Converters.InsertRange(0, Converters); - - if (camelCase) + protected virtual JsonSerializerSettings CreateJsonSerializerOptions(bool camelCase = true, bool indented = false) + { + return JsonSerializerOptionsCache.GetOrAdd(new { - settings.ContractResolver = SharedCamelCaseExceptDictionaryKeysResolver; - } - - if (indented) + camelCase, + indented + }, _ => { - settings.Formatting = Formatting.Indented; - } + var settings = new JsonSerializerSettings(); - return settings; - } + settings.Converters.InsertRange(0, Converters); - private class CamelCaseExceptDictionaryKeysResolver : CamelCasePropertyNamesContractResolver - { - protected override JsonDictionaryContract CreateDictionaryContract(Type objectType) - { - var contract = base.CreateDictionaryContract(objectType); + if (camelCase) + { + settings.ContractResolver = ServiceProvider.GetRequiredService(); + } - contract.DictionaryKeyResolver = propertyName => propertyName; + if (indented) + { + settings.Formatting = Formatting.Indented; + } - return contract; - } + return settings; + }); } } diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo.Abp.Json.SystemTextJson.csproj b/framework/src/Volo.Abp.Json.SystemTextJson/Volo.Abp.Json.SystemTextJson.csproj index c9aa014c82..5402dd3c37 100644 --- a/framework/src/Volo.Abp.Json.SystemTextJson/Volo.Abp.Json.SystemTextJson.csproj +++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo.Abp.Json.SystemTextJson.csproj @@ -17,6 +17,7 @@ + diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpDefaultJsonTypeInfoResolver.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpDefaultJsonTypeInfoResolver.cs new file mode 100644 index 0000000000..385544dc0b --- /dev/null +++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpDefaultJsonTypeInfoResolver.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization.Metadata; +using Microsoft.Extensions.Options; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Json.SystemTextJson; + +public class AbpDefaultJsonTypeInfoResolver : DefaultJsonTypeInfoResolver, ITransientDependency +{ + public AbpDefaultJsonTypeInfoResolver(IOptions options) + { + foreach (var modifier in options.Value.Modifiers) + { + Modifiers.Add(modifier); + } + } +} diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerModifiersOptions.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerModifiersOptions.cs new file mode 100644 index 0000000000..4f4f8d1bac --- /dev/null +++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerModifiersOptions.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization.Metadata; +using Volo.Abp.Data; +using Volo.Abp.Json.SystemTextJson.Modifiers; +using Volo.Abp.ObjectExtending; + +namespace Volo.Abp.Json.SystemTextJson; + +public class AbpSystemTextJsonSerializerModifiersOptions +{ + public List> Modifiers { get; } + + public AbpSystemTextJsonSerializerModifiersOptions() + { + Modifiers = new List> + { + new IncludeNonPublicPropertiesModifiers().CreateModifyAction("ExtraProperties") + }; + } +} 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 index 1615581a9d..a5806b28be 100644 --- 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 @@ -28,5 +28,7 @@ public class AbpSystemTextJsonSerializerOptionsSetup : IConfigureOptions>()); } } diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerProvider.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerProvider.cs index 802dd3f528..43aad3383d 100644 --- a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerProvider.cs +++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerProvider.cs @@ -10,19 +10,14 @@ public class AbpSystemTextJsonSerializerProvider : IJsonSerializerProvider, ITra { protected AbpSystemTextJsonSerializerOptions Options { get; } - protected AbpSystemTextJsonUnsupportedTypeMatcher AbpSystemTextJsonUnsupportedTypeMatcher { get; } - - public AbpSystemTextJsonSerializerProvider( - IOptions options, - AbpSystemTextJsonUnsupportedTypeMatcher abpSystemTextJsonUnsupportedTypeMatcher) + public AbpSystemTextJsonSerializerProvider(IOptions options) { - AbpSystemTextJsonUnsupportedTypeMatcher = abpSystemTextJsonUnsupportedTypeMatcher; Options = options.Value; } public bool CanHandle(Type type) { - return !AbpSystemTextJsonUnsupportedTypeMatcher.Match(type); + return !Options.UnsupportedTypes.Contains(type); } public string Serialize(object obj, bool camelCase = true, bool indented = false) diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonUnsupportedTypeMatcher.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonUnsupportedTypeMatcher.cs deleted file mode 100644 index eecc20c555..0000000000 --- a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonUnsupportedTypeMatcher.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using JetBrains.Annotations; -using Microsoft.Extensions.Options; -using Volo.Abp.DependencyInjection; - -namespace Volo.Abp.Json.SystemTextJson; - -public class AbpSystemTextJsonUnsupportedTypeMatcher : ITransientDependency -{ - protected AbpSystemTextJsonSerializerOptions Options { get; } - - public AbpSystemTextJsonUnsupportedTypeMatcher(IOptions options) - { - Options = options.Value; - } - - public virtual bool Match([CanBeNull] Type type) - { - return Options.UnsupportedTypes.Contains(type); - } -} diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/IncludeNonPublicPropertiesModifiers.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/IncludeNonPublicPropertiesModifiers.cs new file mode 100644 index 0000000000..fcca1d672c --- /dev/null +++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/IncludeNonPublicPropertiesModifiers.cs @@ -0,0 +1,37 @@ +using System; +using System.Linq; +using System.Text.Json.Serialization.Metadata; + +namespace Volo.Abp.Json.SystemTextJson.Modifiers; + +public class IncludeNonPublicPropertiesModifiers + where TClass : class +{ + private string _propertyName; + + public Action CreateModifyAction(string propertyName) + { + _propertyName = propertyName; + return Modify; + } + + public void Modify(JsonTypeInfo jsonTypeInfo) + { + if (jsonTypeInfo.Type == typeof(TClass)) + { + var propertyJsonInfo = jsonTypeInfo.Properties.FirstOrDefault(x => x.Name.Equals(_propertyName, StringComparison.OrdinalIgnoreCase) && x.Set == null); + if (propertyJsonInfo != null) + { + var propertyInfo = typeof(TClass).GetProperty(_propertyName); + if (propertyInfo != null) + { + var jsonPropertyInfo = jsonTypeInfo.CreateJsonPropertyInfo(typeof(TProperty), propertyJsonInfo.Name); + jsonPropertyInfo.Get = propertyInfo.GetValue; + jsonPropertyInfo.Set = propertyInfo.SetValue; + jsonTypeInfo.Properties.Remove(propertyJsonInfo); + jsonTypeInfo.Properties.Add(jsonPropertyInfo); + } + } + } + } +} diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensibleObject.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensibleObject.cs index 4479eeb648..611176b570 100644 --- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensibleObject.cs +++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensibleObject.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; -using System.Text.Json.Serialization; using Volo.Abp.Data; using Volo.Abp.DynamicProxy; @@ -10,7 +9,6 @@ namespace Volo.Abp.ObjectExtending; [Serializable] public class ExtensibleObject : IHasExtraProperties, IValidatableObject { - [JsonInclude] public ExtraPropertyDictionary ExtraProperties { get; protected set; } public ExtensibleObject() diff --git a/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpSystemTextJsonUnsupportedTypeMatcher_Tests.cs b/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpSystemTextJsonUnsupportedTypeMatcher_Tests.cs deleted file mode 100644 index 1c621f3930..0000000000 --- a/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpSystemTextJsonUnsupportedTypeMatcher_Tests.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System; -using System.Collections.Generic; -using Microsoft.Extensions.DependencyInjection; -using Shouldly; -using Volo.Abp.Json.SystemTextJson; -using Xunit; - -namespace Volo.Abp.Json; - -public class AbpSystemTextJsonUnsupportedTypeMatcher_Tests : AbpJsonTestBase -{ - private readonly AbpSystemTextJsonUnsupportedTypeMatcher _abpSystemTextJsonUnsupportedTypeMatcher; - - public AbpSystemTextJsonUnsupportedTypeMatcher_Tests() - { - _abpSystemTextJsonUnsupportedTypeMatcher = GetRequiredService(); - } - - protected override void AfterAddApplication(IServiceCollection services) - { - services.Configure(options => - { - options.UnsupportedTypes.Add(); - options.UnsupportedTypes.Add(); - options.UnsupportedTypes.Add>(); - }); - } - - [Fact] - public void Match_Test() - { - _abpSystemTextJsonUnsupportedTypeMatcher.Match(typeof(MyClass)).ShouldBeTrue(); - _abpSystemTextJsonUnsupportedTypeMatcher.Match(typeof(byte[])).ShouldBeTrue(); - - _abpSystemTextJsonUnsupportedTypeMatcher.Match(typeof(MyClass2)).ShouldBeFalse(); - _abpSystemTextJsonUnsupportedTypeMatcher.Match(typeof(MyClass3)).ShouldBeFalse(); - _abpSystemTextJsonUnsupportedTypeMatcher.Match(typeof(MyClass4)).ShouldBeFalse(); - - _abpSystemTextJsonUnsupportedTypeMatcher.Match(typeof(string)).ShouldBeFalse(); - _abpSystemTextJsonUnsupportedTypeMatcher.Match(typeof(string[])).ShouldBeFalse(); - - _abpSystemTextJsonUnsupportedTypeMatcher.Match(typeof(Dictionary)).ShouldBeTrue(); - _abpSystemTextJsonUnsupportedTypeMatcher.Match(typeof(IDictionary)).ShouldBeFalse(); - } - - class MyClass - { - public DateTime Prop1 { get; set; } - } - - class MyClass2 - { - public DateTime Prop1 { get; set; } - } - - class MyClass3 - { - public MyClass4 Prop1 { get; set; } - } - - class MyClass4 - { - public DateTime Prop1 { get; set; } - } -} diff --git a/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/ExtensibleObjectModifiers_Tests.cs b/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/ExtensibleObjectModifiers_Tests.cs new file mode 100644 index 0000000000..617301bd6c --- /dev/null +++ b/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/ExtensibleObjectModifiers_Tests.cs @@ -0,0 +1,19 @@ +using Shouldly; +using Volo.Abp.Json.SystemTextJson; +using Volo.Abp.ObjectExtending; +using Xunit; + +namespace Volo.Abp.Json; + +public class ExtensibleObjectModifiers_Tests : AbpJsonTestBase +{ + [Fact] + public void Should_Modify_Object() + { + var jsonSerializer = GetRequiredService(); + + var extensibleObject = jsonSerializer.Deserialize("{\"ExtraProperties\": {\"Test-Key\":\"Test-Value\"}}"); + + extensibleObject.ExtraProperties.ShouldContainKeyAndValue("Test-Key", "Test-Value"); + } +} From c59d75be61b69c3122311a7dc65bb5bbb427c28b Mon Sep 17 00:00:00 2001 From: maliming Date: Wed, 17 Aug 2022 11:14:14 +0800 Subject: [PATCH 007/124] Fix unit tests. --- .../Mvc/Json/AbpJsonOptionsSetup.cs | 3 -- .../Newtonsoft/AbpJsonIsoDateTimeConverter.cs | 7 +--- .../Newtonsoft/AbpJsonNewtonsoftModule.cs | 5 --- .../AbpJsonSystemTextJsonModule.cs | 1 + ...ystemTextJsonSerializerModifiersOptions.cs | 5 +-- ...TextJsonSerializerModifiersOptionsSetup.cs | 20 ++++++++++ ...AbpSystemTextJsonSerializerOptionsSetup.cs | 3 -- .../Modifiers/AbpDateTimeConverterModifier.cs | 39 +++++++++++++++++++ .../IncludeExtraPropertiesModifiers.cs | 29 ++++++++++++++ .../ModelBindingController_Tests.cs | 10 ----- 10 files changed, 92 insertions(+), 30 deletions(-) create mode 100644 framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerModifiersOptionsSetup.cs create mode 100644 framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpDateTimeConverterModifier.cs create mode 100644 framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/IncludeExtraPropertiesModifiers.cs 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 650d3890c1..05c57ee5a7 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 @@ -23,9 +23,6 @@ public class AbpJsonOptionsSetup : IConfigureOptions options.JsonSerializerOptions.ReadCommentHandling = JsonCommentHandling.Skip; options.JsonSerializerOptions.AllowTrailingCommas = true; - options.JsonSerializerOptions.Converters.Add(ServiceProvider.GetRequiredService()); - options.JsonSerializerOptions.Converters.Add(ServiceProvider.GetRequiredService()); - options.JsonSerializerOptions.Converters.Add(new AbpStringToEnumFactory()); options.JsonSerializerOptions.Converters.Add(new AbpStringToBooleanConverter()); diff --git a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpJsonIsoDateTimeConverter.cs b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpJsonIsoDateTimeConverter.cs index 660a69e4e7..605f06e9a6 100644 --- a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpJsonIsoDateTimeConverter.cs +++ b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpJsonIsoDateTimeConverter.cs @@ -23,12 +23,7 @@ public class AbpJsonIsoDateTimeConverter : IsoDateTimeConverter, ITransientDepen public override bool CanConvert(Type objectType) { - if (objectType == typeof(DateTime) || objectType == typeof(DateTime?)) - { - return true; - } - - return false; + return objectType == typeof(DateTime) || objectType == typeof(DateTime?); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 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 afa419bba2..e276821bcb 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 @@ -12,10 +12,5 @@ public class AbpJsonNewtonsoftModule : AbpModule { options.Providers.Add(); }); - - Configure(options => - { - options.Converters.Add(); - }); } } 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 895c9bcfe4..ac7e66a7ef 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 @@ -12,6 +12,7 @@ public class AbpJsonSystemTextJsonModule : AbpModule public override void ConfigureServices(ServiceConfigurationContext context) { context.Services.TryAddEnumerable(ServiceDescriptor.Transient, AbpSystemTextJsonSerializerOptionsSetup>()); + context.Services.TryAddEnumerable(ServiceDescriptor.Transient, AbpSystemTextJsonSerializerModifiersOptionsSetup>()); Configure(options => { diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerModifiersOptions.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerModifiersOptions.cs index 4f4f8d1bac..efc0a6a883 100644 --- a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerModifiersOptions.cs +++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerModifiersOptions.cs @@ -1,9 +1,8 @@ using System; using System.Collections.Generic; using System.Text.Json.Serialization.Metadata; -using Volo.Abp.Data; using Volo.Abp.Json.SystemTextJson.Modifiers; -using Volo.Abp.ObjectExtending; + namespace Volo.Abp.Json.SystemTextJson; @@ -15,7 +14,7 @@ public class AbpSystemTextJsonSerializerModifiersOptions { Modifiers = new List> { - new IncludeNonPublicPropertiesModifiers().CreateModifyAction("ExtraProperties") + IncludeExtraPropertiesModifiers.Modify, }; } } 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 new file mode 100644 index 0000000000..f0ee1e9cfb --- /dev/null +++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerModifiersOptionsSetup.cs @@ -0,0 +1,20 @@ +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 index a5806b28be..a9a35c1d47 100644 --- 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 @@ -18,9 +18,6 @@ public class AbpSystemTextJsonSerializerOptionsSetup : IConfigureOptions()); - options.JsonSerializerOptions.Converters.Add(ServiceProvider.GetRequiredService()); - options.JsonSerializerOptions.Converters.Add(new AbpStringToEnumFactory()); options.JsonSerializerOptions.Converters.Add(new AbpStringToBooleanConverter()); diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpDateTimeConverterModifier.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpDateTimeConverterModifier.cs new file mode 100644 index 0000000000..a691423cf3 --- /dev/null +++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpDateTimeConverterModifier.cs @@ -0,0 +1,39 @@ +using System; +using System.Linq; +using System.Text.Json.Serialization.Metadata; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Json.SystemTextJson.JsonConverters; +using Volo.Abp.Reflection; +using Volo.Abp.Timing; + +namespace Volo.Abp.Json.SystemTextJson.Modifiers; + +public class AbpDateTimeConverterModifier +{ + private IServiceProvider _serviceProvider; + + public Action CreateModifyAction(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + return Modify; + } + + private void Modify(JsonTypeInfo jsonTypeInfo) + { + if (ReflectionHelper.GetAttributesOfMemberOrDeclaringType(jsonTypeInfo.Type).Any()) + { + return; + } + + foreach (var property in jsonTypeInfo.Properties.Where(x => x.PropertyType == typeof(DateTime) || x.PropertyType == typeof(DateTime?))) + { + if (property.AttributeProvider == null || + !property.AttributeProvider.GetCustomAttributes(typeof(DisableDateTimeNormalizationAttribute), false).Any()) + { + property.CustomConverter = property.PropertyType == typeof(DateTime) + ? _serviceProvider.GetRequiredService() + : _serviceProvider.GetRequiredService(); + } + } + } +} diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/IncludeExtraPropertiesModifiers.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/IncludeExtraPropertiesModifiers.cs new file mode 100644 index 0000000000..b96a73e1f7 --- /dev/null +++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/IncludeExtraPropertiesModifiers.cs @@ -0,0 +1,29 @@ +using System; +using System.Linq; +using System.Text.Json.Serialization.Metadata; +using Volo.Abp.Data; +using Volo.Abp.ObjectExtending; + +namespace Volo.Abp.Json.SystemTextJson.Modifiers; + +public static class IncludeExtraPropertiesModifiers +{ + public static void Modify(JsonTypeInfo jsonTypeInfo) + { + var propertyJsonInfo = jsonTypeInfo.Properties.FirstOrDefault(x => x.PropertyType == typeof(ExtraPropertyDictionary) && + x.Name.Equals(nameof(ExtensibleObject.ExtraProperties), StringComparison.OrdinalIgnoreCase) && + x.Set == null); + if (propertyJsonInfo != null) + { + var propertyInfo = jsonTypeInfo.Type.GetProperty(nameof(ExtensibleObject.ExtraProperties)); + if (propertyInfo != null) + { + var jsonPropertyInfo = jsonTypeInfo.CreateJsonPropertyInfo(typeof(ExtraPropertyDictionary), propertyJsonInfo.Name); + jsonPropertyInfo.Get = propertyInfo.GetValue; + jsonPropertyInfo.Set = propertyInfo.SetValue; + jsonTypeInfo.Properties.Remove(propertyJsonInfo); + jsonTypeInfo.Properties.Add(jsonPropertyInfo); + } + } + } +} diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ModelBinding/ModelBindingController_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ModelBinding/ModelBindingController_Tests.cs index 0d30d101cb..2850ca82c7 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ModelBinding/ModelBindingController_Tests.cs +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ModelBinding/ModelBindingController_Tests.cs @@ -8,7 +8,6 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Shouldly; using Volo.Abp.Http; -using Volo.Abp.Json.SystemTextJson; using Volo.Abp.Timing; using Xunit; @@ -18,15 +17,6 @@ public abstract class ModelBindingController_Tests : AspNetCoreMvcTestBase { protected DateTimeKind Kind { get; set; } - protected override void ConfigureServices(HostBuilderContext context, IServiceCollection services) - { - services.Configure(options => - { - options.UnsupportedTypes.Add(); - options.UnsupportedTypes.Add(); - }); - } - [Fact] public async Task DateTimeKind_Test() { From d6152d01c2acbcf272b11cf84c83be8ca3418edc Mon Sep 17 00:00:00 2001 From: maliming Date: Wed, 17 Aug 2022 13:15:08 +0800 Subject: [PATCH 008/124] Add `AbpTestServer`. --- .../AbpAspNetCoreIntegratedTestBase.cs | 2 +- .../TestBase/AbpNoopHostLifetime.cs | 18 +++++++ .../TestBase/WebHostBuilderExtensions.cs | 19 +++++++ .../ModelBindingController_Tests.cs | 49 ++++++++++++++++++- 4 files changed, 85 insertions(+), 3 deletions(-) create mode 100644 framework/src/Volo.Abp.AspNetCore.TestBase/Volo/Abp/AspNetCore/TestBase/AbpNoopHostLifetime.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.TestBase/Volo/Abp/AspNetCore/TestBase/WebHostBuilderExtensions.cs diff --git a/framework/src/Volo.Abp.AspNetCore.TestBase/Volo/Abp/AspNetCore/TestBase/AbpAspNetCoreIntegratedTestBase.cs b/framework/src/Volo.Abp.AspNetCore.TestBase/Volo/Abp/AspNetCore/TestBase/AbpAspNetCoreIntegratedTestBase.cs index f3e60979bb..aa2ee0026a 100644 --- a/framework/src/Volo.Abp.AspNetCore.TestBase/Volo/Abp/AspNetCore/TestBase/AbpAspNetCoreIntegratedTestBase.cs +++ b/framework/src/Volo.Abp.AspNetCore.TestBase/Volo/Abp/AspNetCore/TestBase/AbpAspNetCoreIntegratedTestBase.cs @@ -40,7 +40,7 @@ public abstract class AbpAspNetCoreIntegratedTestBase : AbpTestBaseWit .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup(); - webBuilder.UseTestServer(); + webBuilder.UseAbpTestServer(); }) .UseAutofac() .ConfigureServices(ConfigureServices); diff --git a/framework/src/Volo.Abp.AspNetCore.TestBase/Volo/Abp/AspNetCore/TestBase/AbpNoopHostLifetime.cs b/framework/src/Volo.Abp.AspNetCore.TestBase/Volo/Abp/AspNetCore/TestBase/AbpNoopHostLifetime.cs new file mode 100644 index 0000000000..c20cf0db3a --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.TestBase/Volo/Abp/AspNetCore/TestBase/AbpNoopHostLifetime.cs @@ -0,0 +1,18 @@ +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Hosting; + +namespace Volo.Abp.AspNetCore.TestBase; + +public class AbpNoopHostLifetime : IHostLifetime +{ + public Task StopAsync(CancellationToken cancellationToken) + { + return Task.CompletedTask; + } + + public Task WaitForStartAsync(CancellationToken cancellationToken) + { + return Task.CompletedTask; + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.TestBase/Volo/Abp/AspNetCore/TestBase/WebHostBuilderExtensions.cs b/framework/src/Volo.Abp.AspNetCore.TestBase/Volo/Abp/AspNetCore/TestBase/WebHostBuilderExtensions.cs new file mode 100644 index 0000000000..288f6ad569 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.TestBase/Volo/Abp/AspNetCore/TestBase/WebHostBuilderExtensions.cs @@ -0,0 +1,19 @@ +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Hosting.Server; +using Microsoft.AspNetCore.TestHost; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; + +namespace Volo.Abp.AspNetCore.TestBase; + +public static class AbpWebHostBuilderExtensions +{ + public static IWebHostBuilder UseAbpTestServer(this IWebHostBuilder builder) + { + return builder.ConfigureServices(services => + { + services.AddScoped(); + services.AddScoped(); + }); + } +} diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ModelBinding/ModelBindingController_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ModelBinding/ModelBindingController_Tests.cs index 2850ca82c7..b2270adc42 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ModelBinding/ModelBindingController_Tests.cs +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ModelBinding/ModelBindingController_Tests.cs @@ -6,8 +6,10 @@ using System.Text.Json; using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Options; using Shouldly; using Volo.Abp.Http; +using Volo.Abp.Json.SystemTextJson; using Volo.Abp.Timing; using Xunit; @@ -106,7 +108,7 @@ public abstract class ModelBindingController_Tests : AspNetCoreMvcTestBase } } -public class ModelBindingController_Utc_Tests : ModelBindingController_Tests +public abstract class ModelBindingController_Utc_Tests : ModelBindingController_Tests { protected override void ConfigureServices(HostBuilderContext context, IServiceCollection services) { @@ -117,7 +119,7 @@ public class ModelBindingController_Utc_Tests : ModelBindingController_Tests } } -public class ModelBindingController_Local_Tests : ModelBindingController_Tests +public abstract class ModelBindingController_Local_Tests : ModelBindingController_Tests { protected override void ConfigureServices(HostBuilderContext context, IServiceCollection services) { @@ -127,3 +129,46 @@ public class ModelBindingController_Local_Tests : ModelBindingController_Tests base.ConfigureServices(context, services); } } + +public class SystemTextJson_ModelBindingController_Utc_Tests : ModelBindingController_Utc_Tests +{ + +} + +public class SystemTextJson_ModelBindingController_Local_Tests : ModelBindingController_Local_Tests +{ + +} + +public class Newtonsoft_ModelBindingController_Utc_Tests : ModelBindingController_Utc_Tests +{ + protected override void ConfigureServices(HostBuilderContext context, IServiceCollection services) + { + services.Configure(options => + { + options.UnsupportedTypes.Add(); + options.UnsupportedTypes.Add(); + }); + + services.Configure>(x => + { + + }); + + base.ConfigureServices(context, services); + } +} + +public class Newtonsoft_ModelBindingController_Local_Tests : ModelBindingController_Local_Tests +{ + protected override void ConfigureServices(HostBuilderContext context, IServiceCollection services) + { + services.Configure(options => + { + options.UnsupportedTypes.Add(); + options.UnsupportedTypes.Add(); + }); + + base.ConfigureServices(context, services); + } +} From e2748ce82a8bfc8d684bf3bd004eac668eaad937 Mon Sep 17 00:00:00 2001 From: maliming Date: Fri, 19 Aug 2022 20:55:51 +0800 Subject: [PATCH 009/124] Use action replace the `IConfigureOptions` classes. --- .../AbpAspNetCoreMvcNewtonsoftModule.cs | 43 ++++++++------ .../AbpAspNetCoreMvcNewtonsoftOptions.cs | 11 ---- .../AbpMvcNewtonsoftJsonOptionsSetup.cs | 31 ---------- .../Mvc/Json/AbpJsonOptionsSetup.cs | 33 ----------- .../Mvc/Json/MvcCoreBuilderExtensions.cs | 23 ++++++-- .../Newtonsoft/AbpJsonNewtonsoftModule.cs | 9 ++- .../AbpNewtonsoftJsonSerializerOptions.cs | 5 +- .../AbpNewtonsoftJsonSerializerProvider.cs | 59 +++++++++++++------ .../AbpJsonSystemTextJsonModule.cs | 30 ++++++++-- ...TextJsonSerializerModifiersOptionsSetup.cs | 20 ------- ...AbpSystemTextJsonSerializerOptionsSetup.cs | 31 ---------- 11 files changed, 119 insertions(+), 176 deletions(-) delete mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpAspNetCoreMvcNewtonsoftOptions.cs delete mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpMvcNewtonsoftJsonOptionsSetup.cs delete mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpJsonOptionsSetup.cs delete mode 100644 framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerModifiersOptionsSetup.cs delete mode 100644 framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerOptionsSetup.cs 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>()); - } -} From ff2ecc004f8c57ff8d59c468c2390b70fea66e25 Mon Sep 17 00:00:00 2001 From: maliming Date: Sun, 21 Aug 2022 15:34:06 +0800 Subject: [PATCH 010/124] Remove `HybridJson`. --- framework/Volo.Abp.sln | 2 +- ...o.Abp.AspNetCore.Mvc.NewtonsoftJson.csproj | 1 + .../AbpAspNetCoreMvcNewtonsoftModule.cs | 36 +---- .../AbpNewtonsoftJsonFormatter.cs | 65 -------- .../AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs | 4 +- ...tCoreApiDescriptionModelProviderOptions.cs | 11 +- .../Mvc/Json/AbpHybridJsonFormatterOptions.cs | 17 -- .../Mvc/Json/AbpHybridJsonInputFormatter.cs | 44 ------ .../Mvc/Json/AbpHybridJsonOutputFormatter.cs | 42 ----- .../Mvc/Json/AbpSystemTextJsonFormatter.cs | 61 ------- .../Mvc/Json/IAbpHybridJsonInputFormatter.cs | 12 -- .../Mvc/Json/IAbpHybridJsonOutputFormatter.cs | 12 -- .../Mvc/Json/MediaTypeHeaderValues.cs | 21 --- .../Mvc/Json/MvcCoreBuilderExtensions.cs | 16 -- .../Abp/Auditing/AuditingContractResolver.cs | 42 ----- .../Volo/Abp/Auditing/JsonAuditSerializer.cs | 78 +++++++++ .../Abp/Auditing/JsonNetAuditSerializer.cs | 43 ----- .../Volo.Abp.Cli.Core.csproj | 1 + .../Volo/Abp/Cli/AbpCliCoreModule.cs | 8 - .../Volo/Abp/Cli/LIbs/InstallLibsService.cs | 11 +- .../AbpApiProxyScriptingConfiguration.cs | 18 +-- .../FodyWeavers.xml | 0 .../FodyWeavers.xsd | 0 .../Volo.Abp.Json.Abstractions.csproj} | 2 +- .../Abp/Json/AbpJsonAbstractionsModule.cs} | 2 +- .../Volo/Abp/Json/AbpJsonOptions.cs | 9 ++ .../Volo/Abp/Json/IJsonSerializer.cs | 0 .../Volo/Abp/Json/AbpHybridJsonSerializer.cs | 66 -------- .../Volo/Abp/Json/AbpJsonOptions.cs | 18 --- .../Volo/Abp/Json/IJsonSerializerProvider.cs | 15 -- .../Volo.Abp.Json.Newtonsoft.csproj | 2 +- ...pCamelCasePropertyNamesContractResolver.cs | 31 +--- .../Newtonsoft/AbpDefaultContractResolver.cs | 33 ++++ .../Newtonsoft/AbpJsonIsoDateTimeConverter.cs | 14 ++ .../Newtonsoft/AbpJsonNewtonsoftModule.cs | 7 +- ...ider.cs => AbpNewtonsoftJsonSerializer.cs} | 33 ++-- .../Volo.Abp.Json.SystemTextJson.csproj | 2 +- .../AbpJsonSystemTextJsonModule.cs | 7 +- ...ider.cs => AbpSystemTextJsonSerializer.cs} | 12 +- .../AbpSystemTextJsonSerializerOptions.cs | 4 - .../IncludeExtraPropertiesModifiers.cs | 19 +-- .../src/Volo.Abp.Json/Volo.Abp.Json.csproj | 1 - .../Volo/Abp/Json/AbpJsonModule.cs | 5 +- .../Volo.Abp.AspNetCore.Mvc.Tests.csproj | 1 - .../Mvc/AbpAspNetCoreMvcTestModule.cs | 4 +- .../ModelBindingController_Tests.cs | 47 +----- .../Volo/Abp/AspNetCore/Mvc/Startup.cs | 33 +++- ...er_Test.cs => JsonAuditSerializer_Test.cs} | 13 +- .../Abp/Json/AbpHybridJsonSerializer_Tests.cs | 149 ------------------ ...pSystemTextJsonSerializerProvider_Tests.cs | 4 +- .../Json/ExtensibleObjectModifiers_Tests.cs | 2 +- nupkg/common.ps1 | 2 +- 52 files changed, 237 insertions(+), 845 deletions(-) delete mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpNewtonsoftJsonFormatter.cs delete mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonFormatterOptions.cs delete mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonInputFormatter.cs delete mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonOutputFormatter.cs delete mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpSystemTextJsonFormatter.cs delete mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/IAbpHybridJsonInputFormatter.cs delete mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/IAbpHybridJsonOutputFormatter.cs delete mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/MediaTypeHeaderValues.cs delete mode 100644 framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingContractResolver.cs create mode 100644 framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/JsonAuditSerializer.cs delete mode 100644 framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/JsonNetAuditSerializer.cs rename framework/src/{Volo.Abp.Json.Core => Volo.Abp.Json.Abstractions}/FodyWeavers.xml (100%) rename framework/src/{Volo.Abp.Json.Core => Volo.Abp.Json.Abstractions}/FodyWeavers.xsd (100%) rename framework/src/{Volo.Abp.Json.Core/Volo.Abp.Json.Core.csproj => Volo.Abp.Json.Abstractions/Volo.Abp.Json.Abstractions.csproj} (92%) rename framework/src/{Volo.Abp.Json.Core/Volo/Abp/Json/AbpJsonCoreModule.cs => Volo.Abp.Json.Abstractions/Volo/Abp/Json/AbpJsonAbstractionsModule.cs} (54%) create mode 100644 framework/src/Volo.Abp.Json.Abstractions/Volo/Abp/Json/AbpJsonOptions.cs rename framework/src/{Volo.Abp.Json.Core => Volo.Abp.Json.Abstractions}/Volo/Abp/Json/IJsonSerializer.cs (100%) delete mode 100644 framework/src/Volo.Abp.Json.Core/Volo/Abp/Json/AbpHybridJsonSerializer.cs delete mode 100644 framework/src/Volo.Abp.Json.Core/Volo/Abp/Json/AbpJsonOptions.cs delete mode 100644 framework/src/Volo.Abp.Json.Core/Volo/Abp/Json/IJsonSerializerProvider.cs create mode 100644 framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpDefaultContractResolver.cs rename framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/{AbpNewtonsoftJsonSerializerProvider.cs => AbpNewtonsoftJsonSerializer.cs} (80%) rename framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/{AbpSystemTextJsonSerializerProvider.cs => AbpSystemTextJsonSerializer.cs} (76%) rename framework/test/Volo.Abp.Auditing.Tests/Volo/Abp/Auditing/{JsonNetAuditSerializer_Test.cs => JsonAuditSerializer_Test.cs} (78%) delete mode 100644 framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpHybridJsonSerializer_Tests.cs diff --git a/framework/Volo.Abp.sln b/framework/Volo.Abp.sln index b646c5f9e6..27f68c5410 100644 --- a/framework/Volo.Abp.sln +++ b/framework/Volo.Abp.sln @@ -413,7 +413,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Json.Newtonsoft", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Json.SystemTextJson", "src\Volo.Abp.Json.SystemTextJson\Volo.Abp.Json.SystemTextJson.csproj", "{0AD06E14-CBFE-4551-8D18-9E921D8F2A87}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Json.Core", "src\Volo.Abp.Json.Core\Volo.Abp.Json.Core.csproj", "{08531C5D-0436-4721-986D-96446CF54316}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Json.Abstractions", "src\Volo.Abp.Json.Abstractions\Volo.Abp.Json.Abstractions.csproj", "{08531C5D-0436-4721-986D-96446CF54316}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.AspNetCore.Mvc.NewtonsoftJson", "src\Volo.Abp.AspNetCore.Mvc.NewtonsoftJson\Volo.Abp.AspNetCore.Mvc.NewtonsoftJson.csproj", "{0CFC9D4F-F12F-4B44-ABCF-AB4A0E9E85B2}" EndProject diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson.csproj b/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson.csproj index 83ac5bc666..026fb2f4d4 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson.csproj +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson.csproj @@ -19,6 +19,7 @@ + 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 f195f98bf4..6e71fe7b5f 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,47 +1,21 @@ -using System; -using System.Collections.Generic; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.Formatters; +using Microsoft.AspNetCore.Mvc; 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; -[DependsOn(typeof(AbpAspNetCoreMvcModule))] +[DependsOn(typeof(AbpJsonNewtonsoftModule), typeof(AbpAspNetCoreMvcModule))] public class AbpAspNetCoreMvcNewtonsoftModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.TryAddSingleton(); - - Configure(mvcOptions => - { - mvcOptions.InputFormatters.RemoveType(); - mvcOptions.OutputFormatters.RemoveType(); - }); - - Configure(formatterOptions => - { - formatterOptions.TextInputFormatters.Add(); - formatterOptions.TextOutputFormatters.Add(); - }); + context.Services.AddMvcCore().AddNewtonsoftJson(); context.Services.AddOptions() - .Configure((options, serviceProvider) => + .Configure((options, contractResolver) => { - options.SerializerSettings.ContractResolver = serviceProvider.GetRequiredService(); - - var converters = serviceProvider.GetRequiredService>().Value - .Converters.Select(converterType => serviceProvider.GetRequiredService(converterType).As()) - .ToList(); - - options.SerializerSettings.Converters.InsertRange(0, converters); + options.SerializerSettings.ContractResolver = contractResolver; }); } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpNewtonsoftJsonFormatter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpNewtonsoftJsonFormatter.cs deleted file mode 100644 index aa411bfb61..0000000000 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpNewtonsoftJsonFormatter.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System; -using System.Buffers; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.Formatters; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.ObjectPool; -using Microsoft.Extensions.Options; -using Volo.Abp.AspNetCore.Mvc.Json; -using Volo.Abp.DependencyInjection; - -namespace Volo.Abp.AspNetCore.Mvc.NewtonsoftJson; - -public class AbpNewtonsoftJsonFormatter : IAbpHybridJsonInputFormatter, IAbpHybridJsonOutputFormatter, ITransientDependency -{ - private readonly ILoggerFactory _loggerFactory; - private readonly ArrayPool _charPool; - private readonly ObjectPoolProvider _objectPoolProvider; - private readonly IOptions _mvcOptions; - private readonly IOptions _mvcNewtonsoftJsonOptions; - - public AbpNewtonsoftJsonFormatter( - ILoggerFactory loggerFactory, - ArrayPool charPool, - ObjectPoolProvider objectPoolProvider, - IOptions mvcOptions, - IOptions mvcNewtonsoftJsonOptions) - { - _loggerFactory = loggerFactory; - _charPool = charPool; - _objectPoolProvider = objectPoolProvider; - _mvcOptions = mvcOptions; - _mvcNewtonsoftJsonOptions = mvcNewtonsoftJsonOptions; - } - - Task IAbpHybridJsonInputFormatter.CanHandleAsync(Type type) - { - return Task.FromResult(true); - } - - public Task GetTextInputFormatterAsync() - { - return Task.FromResult(new NewtonsoftJsonInputFormatter( - _loggerFactory.CreateLogger(), - _mvcNewtonsoftJsonOptions.Value.SerializerSettings, - _charPool, - _objectPoolProvider, - _mvcOptions.Value, - _mvcNewtonsoftJsonOptions.Value)); - } - - Task IAbpHybridJsonOutputFormatter.CanHandleAsync(Type type) - { - return Task.FromResult(true); - } - - public Task GetTextOutputFormatterAsync() - { - return Task.FromResult(new NewtonsoftJsonOutputFormatter( - _mvcNewtonsoftJsonOptions.Value.SerializerSettings, - _charPool, - _mvcOptions.Value, - _mvcNewtonsoftJsonOptions.Value)); - } -} 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 22b919c91c..20922527bf 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 @@ -38,6 +38,7 @@ using Volo.Abp.GlobalFeatures; using Volo.Abp.Http.Modeling; using Volo.Abp.Http.ProxyScripting.Generators.JQuery; using Volo.Abp.Json; +using Volo.Abp.Json.SystemTextJson; using Volo.Abp.Localization; using Volo.Abp.Modularity; using Volo.Abp.UI; @@ -52,7 +53,8 @@ namespace Volo.Abp.AspNetCore.Mvc; typeof(AbpAspNetCoreMvcContractsModule), typeof(AbpUiNavigationModule), typeof(AbpGlobalFeaturesModule), - typeof(AbpDddApplicationModule) + typeof(AbpDddApplicationModule), + typeof(AbpJsonSystemTextJsonModule) )] public class AbpAspNetCoreMvcModule : AbpModule { diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AspNetCoreApiDescriptionModelProviderOptions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AspNetCoreApiDescriptionModelProviderOptions.cs index 2b9e231874..4dc4a9719a 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AspNetCoreApiDescriptionModelProviderOptions.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AspNetCoreApiDescriptionModelProviderOptions.cs @@ -62,19 +62,12 @@ public class AspNetCoreApiDescriptionModelProviderOptions { if (apiParameterDescription.ModelMetadata is DefaultModelMetadata defaultModelMetadata) { - var jsonPropertyNameAttribute = (System.Text.Json.Serialization.JsonPropertyNameAttribute) - defaultModelMetadata?.Attributes?.PropertyAttributes?.FirstOrDefault(x => x is System.Text.Json.Serialization.JsonPropertyNameAttribute); + var jsonPropertyNameAttribute = (JsonPropertyNameAttribute) + defaultModelMetadata?.Attributes?.PropertyAttributes?.FirstOrDefault(x => x is JsonPropertyNameAttribute); if (jsonPropertyNameAttribute != null) { return jsonPropertyNameAttribute.Name; } - - var jsonPropertyAttribute = (Newtonsoft.Json.JsonPropertyAttribute) - defaultModelMetadata?.Attributes?.PropertyAttributes?.FirstOrDefault(x => x is Newtonsoft.Json.JsonPropertyAttribute); - if (jsonPropertyAttribute != null) - { - return jsonPropertyAttribute.PropertyName; - } } return null; diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonFormatterOptions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonFormatterOptions.cs deleted file mode 100644 index 066ebe4413..0000000000 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonFormatterOptions.cs +++ /dev/null @@ -1,17 +0,0 @@ -using Microsoft.AspNetCore.Mvc.Formatters; -using Volo.Abp.Collections; - -namespace Volo.Abp.AspNetCore.Mvc.Json; - -public class AbpHybridJsonFormatterOptions -{ - public ITypeList TextInputFormatters { get; } - - public ITypeList TextOutputFormatters { get; } - - public AbpHybridJsonFormatterOptions() - { - TextInputFormatters = new TypeList(); - TextOutputFormatters = new TypeList(); - } -} 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 deleted file mode 100644 index 874508ac1f..0000000000 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonInputFormatter.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System; -using System.Text; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc.Formatters; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Options; - -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 (await GetTextInputFormatterAsync(context)).ReadRequestBodyAsync(context, encoding); - } - - protected virtual async Task GetTextInputFormatterAsync(InputFormatterContext context) - { - var options = context.HttpContext.RequestServices.GetRequiredService>().Value; - - foreach (var inputFormatterType in options.TextInputFormatters) - { - var inputFormatter = context.HttpContext.RequestServices.GetRequiredService(inputFormatterType).As(); - if (await inputFormatter.CanHandleAsync(context.ModelType)) - { - return await inputFormatter.GetTextInputFormatterAsync(); - } - } - - throw new AbpException($"The {nameof(AbpHybridJsonInputFormatter)} can't handle '{context.ModelType.GetFullNameWithAssemblyName()}'!"); - } - - public virtual 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 deleted file mode 100644 index 2960ff1635..0000000000 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonOutputFormatter.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System; -using System.Text; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc.Formatters; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Options; - -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 (await GetTextInputFormatter(context)).WriteResponseBodyAsync(context, selectedEncoding); - } - - protected virtual async Task GetTextInputFormatter(OutputFormatterWriteContext context) - { - var options = context.HttpContext.RequestServices.GetRequiredService>().Value; - - foreach (var outputFormatterType in options.TextOutputFormatters) - { - var outputFormatter = context.HttpContext.RequestServices.GetRequiredService(outputFormatterType).As(); - if (await outputFormatter.CanHandleAsync(context.ObjectType)) - { - return await outputFormatter.GetTextOutputFormatterAsync(); - } - } - - throw new AbpException($"The {nameof(AbpHybridJsonOutputFormatter)} can't handle '{context.ObjectType.GetFullNameWithAssemblyName()}'!"); - } -} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpSystemTextJsonFormatter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpSystemTextJsonFormatter.cs deleted file mode 100644 index fb8c509748..0000000000 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpSystemTextJsonFormatter.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System; -using System.Text.Encodings.Web; -using System.Text.Json; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.Formatters; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; -using Volo.Abp.DependencyInjection; -using Volo.Abp.Json.SystemTextJson; - -namespace Volo.Abp.AspNetCore.Mvc.Json; - -public class AbpSystemTextJsonFormatter : IAbpHybridJsonInputFormatter, IAbpHybridJsonOutputFormatter, ITransientDependency -{ - private readonly IOptions _jsonOptions; - private readonly IOptions _systemTextJsonSerializerOptions; - private readonly ILoggerFactory _loggerFactory; - - public AbpSystemTextJsonFormatter( - IOptions jsonOptions, - IOptions systemTextJsonSerializerOptions, - ILoggerFactory loggerFactory) - { - _jsonOptions = jsonOptions; - _systemTextJsonSerializerOptions = systemTextJsonSerializerOptions; - _loggerFactory = loggerFactory; - } - - Task IAbpHybridJsonInputFormatter.CanHandleAsync(Type type) - { - return Task.FromResult(!_systemTextJsonSerializerOptions.Value.UnsupportedTypes.Contains(type)); - } - - public virtual Task GetTextInputFormatterAsync() - { - return Task.FromResult(new SystemTextJsonInputFormatter( - _jsonOptions.Value, - _loggerFactory.CreateLogger())); - } - - Task IAbpHybridJsonOutputFormatter.CanHandleAsync(Type type) - { - return Task.FromResult(!_systemTextJsonSerializerOptions.Value.UnsupportedTypes.Contains(type)); - } - - public Task GetTextOutputFormatterAsync() - { - var jsonSerializerOptions = _jsonOptions.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 Task.FromResult(new SystemTextJsonOutputFormatter(jsonSerializerOptions)); - } -} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/IAbpHybridJsonInputFormatter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/IAbpHybridJsonInputFormatter.cs deleted file mode 100644 index 0a167e58d4..0000000000 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/IAbpHybridJsonInputFormatter.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc.Formatters; - -namespace Volo.Abp.AspNetCore.Mvc.Json; - -public interface IAbpHybridJsonInputFormatter -{ - Task CanHandleAsync(Type type); - - Task GetTextInputFormatterAsync(); -} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/IAbpHybridJsonOutputFormatter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/IAbpHybridJsonOutputFormatter.cs deleted file mode 100644 index 06418b88d4..0000000000 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/IAbpHybridJsonOutputFormatter.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc.Formatters; - -namespace Volo.Abp.AspNetCore.Mvc.Json; - -public interface IAbpHybridJsonOutputFormatter -{ - Task CanHandleAsync(Type type); - - Task GetTextOutputFormatterAsync(); -} 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 deleted file mode 100644 index 23d039ef30..0000000000 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/MediaTypeHeaderValues.cs +++ /dev/null @@ -1,21 +0,0 @@ -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 index ea3f5ea156..66af7b060c 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,7 +1,6 @@ using System; using System.Text.Json; using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.Formatters; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Volo.Abp.Json.SystemTextJson; @@ -13,21 +12,6 @@ public static class MvcCoreBuilderExtensions { public static IMvcCoreBuilder AddAbpHybridJson(this IMvcCoreBuilder builder) { - builder.Services.Configure(options => - { - options.InputFormatters.RemoveType(); - options.InputFormatters.Add(new AbpHybridJsonInputFormatter()); - - options.OutputFormatters.RemoveType(); - options.OutputFormatters.Add(new AbpHybridJsonOutputFormatter()); - }); - - builder.Services.Configure(options => - { - options.TextInputFormatters.Add(); - options.TextOutputFormatters.Add(); - }); - builder.Services.AddOptions() .Configure((options, serviceProvider) => { diff --git a/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingContractResolver.cs b/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingContractResolver.cs deleted file mode 100644 index 77d1b7ddb9..0000000000 --- a/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingContractResolver.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using Newtonsoft.Json; -using Newtonsoft.Json.Serialization; - -namespace Volo.Abp.Auditing; - -public class AuditingContractResolver : CamelCasePropertyNamesContractResolver -{ - private readonly List _ignoredTypes; - - public AuditingContractResolver(List ignoredTypes) - { - _ignoredTypes = ignoredTypes; - } - - protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) - { - var property = base.CreateProperty(member, memberSerialization); - - if (_ignoredTypes.Any(ignoredType => ignoredType.GetTypeInfo().IsAssignableFrom(property.PropertyType))) - { - property.ShouldSerialize = instance => false; - return property; - } - - if (member.DeclaringType != null && (member.DeclaringType.IsDefined(typeof(DisableAuditingAttribute)) || member.DeclaringType.IsDefined(typeof(JsonIgnoreAttribute)))) - { - property.ShouldSerialize = instance => false; - return property; - } - - if (member.IsDefined(typeof(DisableAuditingAttribute)) || member.IsDefined(typeof(JsonIgnoreAttribute))) - { - property.ShouldSerialize = instance => false; - } - - return property; - } -} diff --git a/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/JsonAuditSerializer.cs b/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/JsonAuditSerializer.cs new file mode 100644 index 0000000000..9d8c4248e6 --- /dev/null +++ b/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/JsonAuditSerializer.cs @@ -0,0 +1,78 @@ +using System.Collections.Concurrent; +using System.Linq; +using System.Reflection; +using System.Text.Json; +using System.Text.Json.Serialization.Metadata; +using Microsoft.Extensions.Options; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Auditing; + +public class JsonAuditSerializer : IAuditSerializer, ITransientDependency +{ + protected AbpAuditingOptions Options; + + public JsonAuditSerializer(IOptions options) + { + Options = options.Value; + } + + public string Serialize(object obj) + { + return JsonSerializer.Serialize(obj, CreateJsonSerializerOptions()); + } + + private static readonly ConcurrentDictionary JsonSerializerOptionsCache = + new ConcurrentDictionary(); + + protected virtual JsonSerializerOptions CreateJsonSerializerOptions() + { + return JsonSerializerOptionsCache.GetOrAdd(nameof(JsonAuditSerializer), _ => + { + var settings = new JsonSerializerOptions() + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + TypeInfoResolver = new DefaultJsonTypeInfoResolver() + { + Modifiers = + { + jsonTypeInfo => + { + if (Options.IgnoredTypes.Any(ignoredType => ignoredType.IsAssignableFrom(jsonTypeInfo.Type))) + { + jsonTypeInfo.Properties.Clear(); + } + + if (jsonTypeInfo.Type.GetCustomAttributes(typeof(DisableAuditingAttribute), false).Any()) + { + jsonTypeInfo.Properties.Clear(); + } + + foreach (var property in jsonTypeInfo.Properties) + { + if (Options.IgnoredTypes.Any(ignoredType => ignoredType.IsAssignableFrom(property.PropertyType))) + { + property.ShouldSerialize = (_, _) => false; + } + + if (property.AttributeProvider != null && + property.AttributeProvider.GetCustomAttributes(typeof(DisableAuditingAttribute), false).Any()) + { + property.ShouldSerialize = (_, _) => false; + } + + if (property.PropertyType.DeclaringType != null && + property.PropertyType.DeclaringType.IsDefined(typeof(DisableAuditingAttribute))) + { + property.ShouldSerialize = (_, _) => false; + } + } + } + } + } + }; + + return settings; + }); + } +} diff --git a/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/JsonNetAuditSerializer.cs b/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/JsonNetAuditSerializer.cs deleted file mode 100644 index d5df2b2644..0000000000 --- a/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/JsonNetAuditSerializer.cs +++ /dev/null @@ -1,43 +0,0 @@ -using Microsoft.Extensions.Options; -using Newtonsoft.Json; -using Volo.Abp.DependencyInjection; - -namespace Volo.Abp.Auditing; - -//TODO: Rename to JsonAuditSerializer -public class JsonNetAuditSerializer : IAuditSerializer, ITransientDependency -{ - protected AbpAuditingOptions Options; - - public JsonNetAuditSerializer(IOptions options) - { - Options = options.Value; - } - - public string Serialize(object obj) - { - return JsonConvert.SerializeObject(obj, GetSharedJsonSerializerSettings()); - } - - private static readonly object SyncObj = new object(); - private static JsonSerializerSettings _sharedJsonSerializerSettings; - - private JsonSerializerSettings GetSharedJsonSerializerSettings() - { - if (_sharedJsonSerializerSettings == null) - { - lock (SyncObj) - { - if (_sharedJsonSerializerSettings == null) - { - _sharedJsonSerializerSettings = new JsonSerializerSettings - { - ContractResolver = new AuditingContractResolver(Options.IgnoredTypes) - }; - } - } - } - - return _sharedJsonSerializerSettings; - } -} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo.Abp.Cli.Core.csproj b/framework/src/Volo.Abp.Cli.Core/Volo.Abp.Cli.Core.csproj index 5c83874fa0..1688a4246f 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo.Abp.Cli.Core.csproj +++ b/framework/src/Volo.Abp.Cli.Core/Volo.Abp.Cli.Core.csproj @@ -30,5 +30,6 @@ + diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/AbpCliCoreModule.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/AbpCliCoreModule.cs index 7aba9ae849..28ab693ba1 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/AbpCliCoreModule.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/AbpCliCoreModule.cs @@ -2,17 +2,14 @@ using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Cli.Commands; using Volo.Abp.Cli.Http; -using Volo.Abp.Cli.LIbs; using Volo.Abp.Cli.ServiceProxying; using Volo.Abp.Cli.ServiceProxying.Angular; using Volo.Abp.Cli.ServiceProxying.CSharp; using Volo.Abp.Cli.ServiceProxying.JavaScript; using Volo.Abp.Domain; using Volo.Abp.Http; -using Volo.Abp.Http.ProxyScripting.Generators.JQuery; using Volo.Abp.IdentityModel; using Volo.Abp.Json; -using Volo.Abp.Json.SystemTextJson; using Volo.Abp.Minify; using Volo.Abp.Modularity; @@ -34,11 +31,6 @@ public class AbpCliCoreModule : AbpModule Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); - Configure(options => - { - options.UnsupportedTypes.Add(typeof(ResourceMapping)); - }); - Configure(options => { options.Commands[HelpCommand.Name] = typeof(HelpCommand); diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/LIbs/InstallLibsService.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/LIbs/InstallLibsService.cs index 654feb117b..b925a4220c 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/LIbs/InstallLibsService.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/LIbs/InstallLibsService.cs @@ -7,6 +7,7 @@ using Microsoft.Extensions.FileSystemGlobbing; using Microsoft.Extensions.FileSystemGlobbing.Abstractions; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; +using Newtonsoft.Json; using NuGet.Versioning; using Volo.Abp.Cli.Utils; using Volo.Abp.DependencyInjection; @@ -30,12 +31,9 @@ public class InstallLibsService : IInstallLibsService, ITransientDependency public ILogger Logger { get; set; } - private readonly IJsonSerializer _jsonSerializer; - - public InstallLibsService(IJsonSerializer jsonSerializer, NpmHelper npmHelper) + public InstallLibsService(NpmHelper npmHelper) { NpmHelper = npmHelper; - _jsonSerializer = jsonSerializer; } public async Task InstallLibsAsync(string directory) @@ -119,7 +117,7 @@ public class InstallLibsService : IInstallLibsService, ITransientDependency { return false; } - + using (var reader = File.OpenText(file)) { return reader.ReadToEnd().Contains("Microsoft.NET.Sdk.Web"); @@ -145,7 +143,8 @@ public class InstallLibsService : IInstallLibsService, ITransientDependency { var mappingFileContent = await reader.ReadToEndAsync(); - var mapping = _jsonSerializer.Deserialize(mappingFileContent + // System.Text.Json doesn't support the property name without quotes. + var mapping = Newtonsoft.Json.JsonConvert.DeserializeObject(mappingFileContent .Replace("module.exports", string.Empty) .Replace("=", string.Empty).Trim().TrimEnd(';')); diff --git a/framework/src/Volo.Abp.Http/Volo/Abp/Http/ProxyScripting/Configuration/AbpApiProxyScriptingConfiguration.cs b/framework/src/Volo.Abp.Http/Volo/Abp/Http/ProxyScripting/Configuration/AbpApiProxyScriptingConfiguration.cs index e8da5693f6..86449c8971 100644 --- a/framework/src/Volo.Abp.Http/Volo/Abp/Http/ProxyScripting/Configuration/AbpApiProxyScriptingConfiguration.cs +++ b/framework/src/Volo.Abp.Http/Volo/Abp/Http/ProxyScripting/Configuration/AbpApiProxyScriptingConfiguration.cs @@ -10,22 +10,6 @@ public static class AbpApiProxyScriptingConfiguration static AbpApiProxyScriptingConfiguration() { PropertyNameGenerator = propertyInfo => - { - var jsonPropertyNameAttribute = propertyInfo.GetSingleAttributeOrNull(true); - - if (jsonPropertyNameAttribute != null) - { - return jsonPropertyNameAttribute.Name; - } - - var jsonPropertyAttribute = propertyInfo.GetSingleAttributeOrNull(true); - - if (jsonPropertyAttribute != null) - { - return jsonPropertyAttribute.PropertyName; - } - - return null; - }; + propertyInfo.GetSingleAttributeOrNull()?.Name; } } diff --git a/framework/src/Volo.Abp.Json.Core/FodyWeavers.xml b/framework/src/Volo.Abp.Json.Abstractions/FodyWeavers.xml similarity index 100% rename from framework/src/Volo.Abp.Json.Core/FodyWeavers.xml rename to framework/src/Volo.Abp.Json.Abstractions/FodyWeavers.xml diff --git a/framework/src/Volo.Abp.Json.Core/FodyWeavers.xsd b/framework/src/Volo.Abp.Json.Abstractions/FodyWeavers.xsd similarity index 100% rename from framework/src/Volo.Abp.Json.Core/FodyWeavers.xsd rename to framework/src/Volo.Abp.Json.Abstractions/FodyWeavers.xsd diff --git a/framework/src/Volo.Abp.Json.Core/Volo.Abp.Json.Core.csproj b/framework/src/Volo.Abp.Json.Abstractions/Volo.Abp.Json.Abstractions.csproj similarity index 92% rename from framework/src/Volo.Abp.Json.Core/Volo.Abp.Json.Core.csproj rename to framework/src/Volo.Abp.Json.Abstractions/Volo.Abp.Json.Abstractions.csproj index b7a88c22f6..15130c129c 100644 --- a/framework/src/Volo.Abp.Json.Core/Volo.Abp.Json.Core.csproj +++ b/framework/src/Volo.Abp.Json.Abstractions/Volo.Abp.Json.Abstractions.csproj @@ -5,7 +5,7 @@ netstandard2.0 - Volo.Abp.Json.Core + Volo.Abp.Json.Abstractions $(AssetTargetFallback);portable-net45+win8+wp8+wpa81; false false diff --git a/framework/src/Volo.Abp.Json.Core/Volo/Abp/Json/AbpJsonCoreModule.cs b/framework/src/Volo.Abp.Json.Abstractions/Volo/Abp/Json/AbpJsonAbstractionsModule.cs similarity index 54% rename from framework/src/Volo.Abp.Json.Core/Volo/Abp/Json/AbpJsonCoreModule.cs rename to framework/src/Volo.Abp.Json.Abstractions/Volo/Abp/Json/AbpJsonAbstractionsModule.cs index 68de7be35e..422d34745d 100644 --- a/framework/src/Volo.Abp.Json.Core/Volo/Abp/Json/AbpJsonCoreModule.cs +++ b/framework/src/Volo.Abp.Json.Abstractions/Volo/Abp/Json/AbpJsonAbstractionsModule.cs @@ -2,7 +2,7 @@ namespace Volo.Abp.Json; -public class AbpJsonCoreModule : AbpModule +public class AbpJsonAbstractionsModule : AbpModule { } diff --git a/framework/src/Volo.Abp.Json.Abstractions/Volo/Abp/Json/AbpJsonOptions.cs b/framework/src/Volo.Abp.Json.Abstractions/Volo/Abp/Json/AbpJsonOptions.cs new file mode 100644 index 0000000000..f7f5370255 --- /dev/null +++ b/framework/src/Volo.Abp.Json.Abstractions/Volo/Abp/Json/AbpJsonOptions.cs @@ -0,0 +1,9 @@ +namespace Volo.Abp.Json; + +public class AbpJsonOptions +{ + /// + /// Used to set default value for the DateTimeFormat. + /// + public string DefaultDateTimeFormat { get; set; } +} diff --git a/framework/src/Volo.Abp.Json.Core/Volo/Abp/Json/IJsonSerializer.cs b/framework/src/Volo.Abp.Json.Abstractions/Volo/Abp/Json/IJsonSerializer.cs similarity index 100% rename from framework/src/Volo.Abp.Json.Core/Volo/Abp/Json/IJsonSerializer.cs rename to framework/src/Volo.Abp.Json.Abstractions/Volo/Abp/Json/IJsonSerializer.cs diff --git a/framework/src/Volo.Abp.Json.Core/Volo/Abp/Json/AbpHybridJsonSerializer.cs b/framework/src/Volo.Abp.Json.Core/Volo/Abp/Json/AbpHybridJsonSerializer.cs deleted file mode 100644 index f61f8b78ce..0000000000 --- a/framework/src/Volo.Abp.Json.Core/Volo/Abp/Json/AbpHybridJsonSerializer.cs +++ /dev/null @@ -1,66 +0,0 @@ -using System; -using System.Linq; -using JetBrains.Annotations; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Options; -using Volo.Abp.DependencyInjection; - -namespace Volo.Abp.Json; - -public class AbpHybridJsonSerializer : IJsonSerializer, ITransientDependency -{ - protected AbpJsonOptions Options { get; } - - protected IServiceScopeFactory ServiceScopeFactory { get; } - - public AbpHybridJsonSerializer(IOptions options, IServiceScopeFactory serviceScopeFactory) - { - Options = options.Value; - ServiceScopeFactory = serviceScopeFactory; - } - - public string Serialize([CanBeNull] object obj, bool camelCase = true, bool indented = false) - { - using (var scope = ServiceScopeFactory.CreateScope()) - { - var serializerProvider = GetSerializerProvider(scope.ServiceProvider, obj?.GetType()); - return serializerProvider.Serialize(obj, camelCase, indented); - } - } - - public T Deserialize([NotNull] string jsonString, bool camelCase = true) - { - Check.NotNull(jsonString, nameof(jsonString)); - - using (var scope = ServiceScopeFactory.CreateScope()) - { - var serializerProvider = GetSerializerProvider(scope.ServiceProvider, typeof(T)); - return serializerProvider.Deserialize(jsonString, camelCase); - } - } - - public object Deserialize(Type type, [NotNull] string jsonString, bool camelCase = true) - { - Check.NotNull(jsonString, nameof(jsonString)); - - using (var scope = ServiceScopeFactory.CreateScope()) - { - var serializerProvider = GetSerializerProvider(scope.ServiceProvider, type); - return serializerProvider.Deserialize(type, jsonString, camelCase); - } - } - - protected virtual IJsonSerializerProvider GetSerializerProvider(IServiceProvider serviceProvider, [CanBeNull] Type type) - { - foreach (var providerType in Options.Providers.Reverse()) - { - var provider = serviceProvider.GetRequiredService(providerType) as IJsonSerializerProvider; - if (provider.CanHandle(type)) - { - return provider; - } - } - - throw new AbpException($"There is no IJsonSerializerProvider that can handle '{type.GetFullNameWithAssemblyName()}'!"); - } -} diff --git a/framework/src/Volo.Abp.Json.Core/Volo/Abp/Json/AbpJsonOptions.cs b/framework/src/Volo.Abp.Json.Core/Volo/Abp/Json/AbpJsonOptions.cs deleted file mode 100644 index ffbd510b93..0000000000 --- a/framework/src/Volo.Abp.Json.Core/Volo/Abp/Json/AbpJsonOptions.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Volo.Abp.Collections; - -namespace Volo.Abp.Json; - -public class AbpJsonOptions -{ - /// - /// 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.Core/Volo/Abp/Json/IJsonSerializerProvider.cs b/framework/src/Volo.Abp.Json.Core/Volo/Abp/Json/IJsonSerializerProvider.cs deleted file mode 100644 index c3ae179d45..0000000000 --- a/framework/src/Volo.Abp.Json.Core/Volo/Abp/Json/IJsonSerializerProvider.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using JetBrains.Annotations; - -namespace Volo.Abp.Json; - -public interface IJsonSerializerProvider -{ - bool CanHandle([CanBeNull] 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.csproj b/framework/src/Volo.Abp.Json.Newtonsoft/Volo.Abp.Json.Newtonsoft.csproj index d53a9e2b33..6927cff0db 100644 --- a/framework/src/Volo.Abp.Json.Newtonsoft/Volo.Abp.Json.Newtonsoft.csproj +++ b/framework/src/Volo.Abp.Json.Newtonsoft/Volo.Abp.Json.Newtonsoft.csproj @@ -15,7 +15,7 @@ - + diff --git a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpCamelCasePropertyNamesContractResolver.cs b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpCamelCasePropertyNamesContractResolver.cs index 502265db84..a73213af6c 100644 --- a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpCamelCasePropertyNamesContractResolver.cs +++ b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpCamelCasePropertyNamesContractResolver.cs @@ -4,8 +4,6 @@ using Microsoft.Extensions.DependencyInjection; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using Volo.Abp.DependencyInjection; -using Volo.Abp.Reflection; -using Volo.Abp.Timing; namespace Volo.Abp.Json.Newtonsoft; @@ -20,38 +18,21 @@ public class AbpCamelCasePropertyNamesContractResolver : CamelCasePropertyNamesC true ); - NamingStrategy = new CamelCaseNamingStrategy(); + NamingStrategy = new CamelCaseNamingStrategy + { + ProcessDictionaryKeys = false + }; } 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) + if (AbpJsonIsoDateTimeConverter.ShouldNormalize(member, property)) { property.Converter = _dateTimeConverter.Value; } - } - protected override JsonDictionaryContract CreateDictionaryContract(Type objectType) - { - var contract = base.CreateDictionaryContract(objectType); - - contract.DictionaryKeyResolver = propertyName => propertyName; - - return contract; + return property; } } diff --git a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpDefaultContractResolver.cs b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpDefaultContractResolver.cs new file mode 100644 index 0000000000..f39f6af578 --- /dev/null +++ b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpDefaultContractResolver.cs @@ -0,0 +1,33 @@ +using System; +using System.Reflection; +using Microsoft.Extensions.DependencyInjection; +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Json.Newtonsoft; + +public class AbpDefaultContractResolver : DefaultContractResolver, ITransientDependency +{ + private readonly Lazy _dateTimeConverter; + + public AbpDefaultContractResolver(IServiceProvider serviceProvider) + { + _dateTimeConverter = new Lazy( + serviceProvider.GetRequiredService, + true + ); + } + + protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) + { + var property = base.CreateProperty(member, memberSerialization); + + if (AbpJsonIsoDateTimeConverter.ShouldNormalize(member, property)) + { + property.Converter = _dateTimeConverter.Value; + } + + return property; + } +} diff --git a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpJsonIsoDateTimeConverter.cs b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpJsonIsoDateTimeConverter.cs index 605f06e9a6..b859688a0d 100644 --- a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpJsonIsoDateTimeConverter.cs +++ b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpJsonIsoDateTimeConverter.cs @@ -1,8 +1,11 @@ using System; +using System.Reflection; using Microsoft.Extensions.Options; using Newtonsoft.Json; using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Serialization; using Volo.Abp.DependencyInjection; +using Volo.Abp.Reflection; using Volo.Abp.Timing; namespace Volo.Abp.Json.Newtonsoft; @@ -43,4 +46,15 @@ public class AbpJsonIsoDateTimeConverter : IsoDateTimeConverter, ITransientDepen var date = value as DateTime?; base.WriteJson(writer, date.HasValue ? _clock.Normalize(date.Value) : value, serializer); } + + internal static bool ShouldNormalize(MemberInfo member, JsonProperty property) + { + if (property.PropertyType != typeof(DateTime) && + property.PropertyType != typeof(DateTime?)) + { + return false; + } + + return ReflectionHelper.GetSingleAttributeOfMemberOrDeclaringTypeOrDefault(member) == null; + } } 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 0989dfdd03..c1f1f3a0cf 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 @@ -4,16 +4,11 @@ using Volo.Abp.Timing; namespace Volo.Abp.Json.Newtonsoft; -[DependsOn(typeof(AbpJsonCoreModule), typeof(AbpTimingModule))] +[DependsOn(typeof(AbpJsonAbstractionsModule), typeof(AbpTimingModule))] public class AbpJsonNewtonsoftModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { - Configure(options => - { - options.Providers.Add(); - }); - context.Services.AddOptions() .Configure((options, contractResolver) => { 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/AbpNewtonsoftJsonSerializer.cs similarity index 80% rename from framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializerProvider.cs rename to framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializer.cs index a23580bf6c..36ba95e74c 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/AbpNewtonsoftJsonSerializer.cs @@ -1,25 +1,24 @@ using System; using System.Collections.Concurrent; -using System.Collections.Generic; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Newtonsoft.Json; using Volo.Abp.DependencyInjection; + namespace Volo.Abp.Json.Newtonsoft; -public class AbpNewtonsoftJsonSerializerProvider : IJsonSerializerProvider, ITransientDependency +[Dependency(ReplaceServices = true)] +public class AbpNewtonsoftJsonSerializer : IJsonSerializer, ITransientDependency { + protected IServiceProvider ServiceProvider { get; } protected IOptions Options { get; } - public AbpNewtonsoftJsonSerializerProvider(IOptions options) + public AbpNewtonsoftJsonSerializer(IServiceProvider serviceProvider, IOptions options) { + ServiceProvider = serviceProvider; Options = options; } - public bool CanHandle(Type type) - { - return true; - } - public string Serialize(object obj, bool camelCase = true, bool indented = false) { return JsonConvert.SerializeObject(obj, CreateJsonSerializerOptions(camelCase, indented)); @@ -35,8 +34,8 @@ public class AbpNewtonsoftJsonSerializerProvider : IJsonSerializerProvider, ITra return JsonConvert.DeserializeObject(jsonString, type, CreateJsonSerializerOptions(camelCase)); } - private readonly static ConcurrentDictionary JsonSerializerOptionsCache = new ConcurrentDictionary(); - + private static readonly ConcurrentDictionary JsonSerializerOptionsCache = + new ConcurrentDictionary(); protected virtual JsonSerializerSettings CreateJsonSerializerOptions(bool camelCase = true, bool indented = false) { @@ -46,8 +45,10 @@ public class AbpNewtonsoftJsonSerializerProvider : IJsonSerializerProvider, ITra indented }, _ => { - var settings = new JsonSerializerSettings { - Binder = Options.Value.JsonSerializerSettings.Binder, CheckAdditionalContent = Options.Value.JsonSerializerSettings.CheckAdditionalContent, + 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, @@ -80,11 +81,9 @@ public class AbpNewtonsoftJsonSerializerProvider : IJsonSerializerProvider, ITra TypeNameAssemblyFormatHandling = Options.Value.JsonSerializerSettings.TypeNameAssemblyFormatHandling }; - - // if (camelCase) - // { - // settings.ContractResolver = ServiceProvider.GetRequiredService(); - // } + settings.ContractResolver = camelCase + ? ServiceProvider.GetRequiredService() + : ServiceProvider.GetRequiredService(); if (indented) { diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo.Abp.Json.SystemTextJson.csproj b/framework/src/Volo.Abp.Json.SystemTextJson/Volo.Abp.Json.SystemTextJson.csproj index 5402dd3c37..b3aba746a3 100644 --- a/framework/src/Volo.Abp.Json.SystemTextJson/Volo.Abp.Json.SystemTextJson.csproj +++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo.Abp.Json.SystemTextJson.csproj @@ -15,7 +15,7 @@ - + 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 178d0aa6a1..50dd47d9e2 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 @@ -9,16 +9,11 @@ using Volo.Abp.Timing; namespace Volo.Abp.Json.SystemTextJson; -[DependsOn(typeof(AbpJsonCoreModule), typeof(AbpTimingModule))] +[DependsOn(typeof(AbpJsonAbstractionsModule), typeof(AbpTimingModule))] public class AbpJsonSystemTextJsonModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { - Configure(options => - { - options.Providers.Add(); - }); - context.Services.AddOptions() .Configure((options, serviceProvider) => { diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerProvider.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializer.cs similarity index 76% rename from framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerProvider.cs rename to framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializer.cs index 43aad3383d..8313f6ee99 100644 --- a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerProvider.cs +++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializer.cs @@ -6,20 +6,15 @@ using Volo.Abp.DependencyInjection; namespace Volo.Abp.Json.SystemTextJson; -public class AbpSystemTextJsonSerializerProvider : IJsonSerializerProvider, ITransientDependency +public class AbpSystemTextJsonSerializer : IJsonSerializer, ITransientDependency { protected AbpSystemTextJsonSerializerOptions Options { get; } - public AbpSystemTextJsonSerializerProvider(IOptions options) + public AbpSystemTextJsonSerializer(IOptions options) { Options = options.Value; } - public bool CanHandle(Type type) - { - return !Options.UnsupportedTypes.Contains(type); - } - public string Serialize(object obj, bool camelCase = true, bool indented = false) { return JsonSerializer.Serialize(obj, CreateJsonSerializerOptions(camelCase, indented)); @@ -35,7 +30,8 @@ public class AbpSystemTextJsonSerializerProvider : IJsonSerializerProvider, ITra return JsonSerializer.Deserialize(jsonString, type, CreateJsonSerializerOptions(camelCase)); } - private readonly static ConcurrentDictionary JsonSerializerOptionsCache = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary JsonSerializerOptionsCache = + new ConcurrentDictionary(); protected virtual JsonSerializerOptions CreateJsonSerializerOptions(bool camelCase = true, bool indented = false) { diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerOptions.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerOptions.cs index f9d6e1a5d9..7288be03c0 100644 --- a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerOptions.cs +++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerOptions.cs @@ -7,8 +7,6 @@ public class AbpSystemTextJsonSerializerOptions { public JsonSerializerOptions JsonSerializerOptions { get; } - public ITypeList UnsupportedTypes { get; } - public AbpSystemTextJsonSerializerOptions() { JsonSerializerOptions = new JsonSerializerOptions(JsonSerializerDefaults.Web) @@ -16,7 +14,5 @@ public class AbpSystemTextJsonSerializerOptions ReadCommentHandling = JsonCommentHandling.Skip, AllowTrailingCommas = true }; - - UnsupportedTypes = new TypeList(); } } diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/IncludeExtraPropertiesModifiers.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/IncludeExtraPropertiesModifiers.cs index b96a73e1f7..a3168fa76f 100644 --- a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/IncludeExtraPropertiesModifiers.cs +++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/IncludeExtraPropertiesModifiers.cs @@ -10,20 +10,17 @@ public static class IncludeExtraPropertiesModifiers { public static void Modify(JsonTypeInfo jsonTypeInfo) { - var propertyJsonInfo = jsonTypeInfo.Properties.FirstOrDefault(x => x.PropertyType == typeof(ExtraPropertyDictionary) && - x.Name.Equals(nameof(ExtensibleObject.ExtraProperties), StringComparison.OrdinalIgnoreCase) && - x.Set == null); + var propertyJsonInfo = jsonTypeInfo.Properties.FirstOrDefault(x => + x.PropertyType == typeof(ExtraPropertyDictionary) && + x.Name.Equals(nameof(ExtensibleObject.ExtraProperties), StringComparison.OrdinalIgnoreCase) && + x.Set == null); + if (propertyJsonInfo != null) { - var propertyInfo = jsonTypeInfo.Type.GetProperty(nameof(ExtensibleObject.ExtraProperties)); - if (propertyInfo != null) + propertyJsonInfo.Set = (extraProperties, value) => { - var jsonPropertyInfo = jsonTypeInfo.CreateJsonPropertyInfo(typeof(ExtraPropertyDictionary), propertyJsonInfo.Name); - jsonPropertyInfo.Get = propertyInfo.GetValue; - jsonPropertyInfo.Set = propertyInfo.SetValue; - jsonTypeInfo.Properties.Remove(propertyJsonInfo); - jsonTypeInfo.Properties.Add(jsonPropertyInfo); - } + ObjectHelper.TrySetProperty(extraProperties.As(), x => x.ExtraProperties, () => (ExtraPropertyDictionary)value); + }; } } } diff --git a/framework/src/Volo.Abp.Json/Volo.Abp.Json.csproj b/framework/src/Volo.Abp.Json/Volo.Abp.Json.csproj index fd0408acba..eee618b18d 100644 --- a/framework/src/Volo.Abp.Json/Volo.Abp.Json.csproj +++ b/framework/src/Volo.Abp.Json/Volo.Abp.Json.csproj @@ -15,7 +15,6 @@ - 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 ef9419a784..b3b9c459b6 100644 --- a/framework/src/Volo.Abp.Json/Volo/Abp/Json/AbpJsonModule.cs +++ b/framework/src/Volo.Abp.Json/Volo/Abp/Json/AbpJsonModule.cs @@ -1,10 +1,9 @@ -using Volo.Abp.Json.Newtonsoft; -using Volo.Abp.Json.SystemTextJson; +using Volo.Abp.Json.SystemTextJson; using Volo.Abp.Modularity; namespace Volo.Abp.Json; -[DependsOn(typeof(AbpJsonNewtonsoftModule), typeof(AbpJsonSystemTextJsonModule))] +[DependsOn(typeof(AbpJsonSystemTextJsonModule))] public class AbpJsonModule : AbpModule { diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo.Abp.AspNetCore.Mvc.Tests.csproj b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo.Abp.AspNetCore.Mvc.Tests.csproj index be8f77271d..930cdb5855 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo.Abp.AspNetCore.Mvc.Tests.csproj +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo.Abp.AspNetCore.Mvc.Tests.csproj @@ -25,7 +25,6 @@ - diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs index 76a95a09cf..d8a49abf23 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs @@ -7,11 +7,9 @@ using Microsoft.AspNetCore.Mvc.Razor; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations; -using Volo.Abp.AspNetCore.Mvc.Authorization; using Volo.Abp.AspNetCore.Mvc.GlobalFeatures; using Volo.Abp.AspNetCore.Mvc.Localization; using Volo.Abp.AspNetCore.Mvc.Localization.Resource; -using Volo.Abp.AspNetCore.Mvc.NewtonsoftJson; using Volo.Abp.AspNetCore.Security.Claims; using Volo.Abp.AspNetCore.TestBase; using Volo.Abp.Authorization; @@ -30,7 +28,7 @@ namespace Volo.Abp.AspNetCore.Mvc; [DependsOn( typeof(AbpAspNetCoreTestBaseModule), typeof(AbpMemoryDbTestModule), - typeof(AbpAspNetCoreMvcNewtonsoftModule), + typeof(AbpAspNetCoreMvcModule), typeof(AbpAutofacModule) )] public class AbpAspNetCoreMvcTestModule : AbpModule diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ModelBinding/ModelBindingController_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ModelBinding/ModelBindingController_Tests.cs index b2270adc42..befbd169fa 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ModelBinding/ModelBindingController_Tests.cs +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ModelBinding/ModelBindingController_Tests.cs @@ -108,7 +108,7 @@ public abstract class ModelBindingController_Tests : AspNetCoreMvcTestBase } } -public abstract class ModelBindingController_Utc_Tests : ModelBindingController_Tests +public class ModelBindingController_Utc_Tests : ModelBindingController_Tests { protected override void ConfigureServices(HostBuilderContext context, IServiceCollection services) { @@ -119,7 +119,7 @@ public abstract class ModelBindingController_Utc_Tests : ModelBindingController_ } } -public abstract class ModelBindingController_Local_Tests : ModelBindingController_Tests +public class ModelBindingController_Local_Tests : ModelBindingController_Tests { protected override void ConfigureServices(HostBuilderContext context, IServiceCollection services) { @@ -129,46 +129,3 @@ public abstract class ModelBindingController_Local_Tests : ModelBindingControlle base.ConfigureServices(context, services); } } - -public class SystemTextJson_ModelBindingController_Utc_Tests : ModelBindingController_Utc_Tests -{ - -} - -public class SystemTextJson_ModelBindingController_Local_Tests : ModelBindingController_Local_Tests -{ - -} - -public class Newtonsoft_ModelBindingController_Utc_Tests : ModelBindingController_Utc_Tests -{ - protected override void ConfigureServices(HostBuilderContext context, IServiceCollection services) - { - services.Configure(options => - { - options.UnsupportedTypes.Add(); - options.UnsupportedTypes.Add(); - }); - - services.Configure>(x => - { - - }); - - base.ConfigureServices(context, services); - } -} - -public class Newtonsoft_ModelBindingController_Local_Tests : ModelBindingController_Local_Tests -{ - protected override void ConfigureServices(HostBuilderContext context, IServiceCollection services) - { - services.Configure(options => - { - options.UnsupportedTypes.Add(); - options.UnsupportedTypes.Add(); - }); - - base.ConfigureServices(context, services); - } -} diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Startup.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Startup.cs index ad4a222c33..df5a8b7b9c 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Startup.cs +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Startup.cs @@ -1,4 +1,6 @@ -using System.IO; +using System; +using System.IO; +using System.Linq; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; @@ -14,13 +16,34 @@ public class Startup services.AddApplication(options => { var hostEnvironment = services.GetHostingEnvironment(); + var currentDirectory = hostEnvironment.ContentRootPath; + var plugDllInPath = ""; + + for (var i = 0; i < 10; i++) + { + var parentDirectory = new DirectoryInfo(currentDirectory).Parent; + if (parentDirectory == null) + { + break; + } + + if (parentDirectory.Name == "test") + { #if DEBUG - var plugDllInPath = Path.Combine(hostEnvironment.ContentRootPath, - @"..\..\..\..\..\Volo.Abp.AspNetCore.Mvc.PlugIn\bin\Debug\net7.0\"); + plugDllInPath = Path.Combine(parentDirectory.FullName, "Volo.Abp.AspNetCore.Mvc.PlugIn", "bin", "Debug", "net7.0"); #else - plugDllInPath = Path.Combine(_env.ContentRootPath, - @"..\..\..\..\..\Volo.Abp.AspNetCore.Mvc.PlugIn\bin\Release\net7.0\"); + plugDllInPath = Path.Combine(parentDirectory.FullName, "Volo.Abp.AspNetCore.Mvc.PlugIn", "bin", "Release", "net7.0"); #endif + break; + } + + currentDirectory = parentDirectory.FullName; + } + + if (plugDllInPath.IsNullOrWhiteSpace()) + { + throw new AbpException("Could not find the plug DLL path!"); + } options.PlugInSources.AddFolder(plugDllInPath); }); diff --git a/framework/test/Volo.Abp.Auditing.Tests/Volo/Abp/Auditing/JsonNetAuditSerializer_Test.cs b/framework/test/Volo.Abp.Auditing.Tests/Volo/Abp/Auditing/JsonAuditSerializer_Test.cs similarity index 78% rename from framework/test/Volo.Abp.Auditing.Tests/Volo/Abp/Auditing/JsonNetAuditSerializer_Test.cs rename to framework/test/Volo.Abp.Auditing.Tests/Volo/Abp/Auditing/JsonAuditSerializer_Test.cs index 1dc3fcf839..cc20805947 100644 --- a/framework/test/Volo.Abp.Auditing.Tests/Volo/Abp/Auditing/JsonNetAuditSerializer_Test.cs +++ b/framework/test/Volo.Abp.Auditing.Tests/Volo/Abp/Auditing/JsonAuditSerializer_Test.cs @@ -1,18 +1,19 @@ using System; using System.Collections.Generic; +using System.Text.Json.Serialization; using Microsoft.Extensions.DependencyInjection; using Shouldly; using Xunit; namespace Volo.Abp.Auditing; -public class JsonNetAuditSerializer_Test : AbpAuditingTestBase +public class JsonAuditSerializer_Test : AbpAuditingTestBase { - private readonly JsonNetAuditSerializer _jsonNetAuditSerializer; + private readonly JsonAuditSerializer _jsonAuditSerializer; - public JsonNetAuditSerializer_Test() + public JsonAuditSerializer_Test() { - _jsonNetAuditSerializer = GetRequiredService(); + _jsonAuditSerializer = GetRequiredService(); } protected override void AfterAddApplication(IServiceCollection services) @@ -34,7 +35,7 @@ public class JsonNetAuditSerializer_Test : AbpAuditingTestBase {"input2", new Input2Dto {UserName = "admin", Password = "1q2w3E*", Birthday = DateTime.Now}} }; - var str = _jsonNetAuditSerializer.Serialize(arguments); + var str = _jsonAuditSerializer.Serialize(arguments); str.ShouldNotContain("IdCard"); str.ShouldNotContain("1q2w3E*"); @@ -58,7 +59,7 @@ public class JsonNetAuditSerializer_Test : AbpAuditingTestBase [DisableAuditing] public string Password { get; set; } - [Newtonsoft.Json.JsonIgnore] + [JsonIgnore] public string PrivateEmail { get; set; } public DateTime Birthday { get; set; } 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 deleted file mode 100644 index 5733d739d2..0000000000 --- a/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpHybridJsonSerializer_Tests.cs +++ /dev/null @@ -1,149 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text.Json; -using Microsoft.Extensions.DependencyInjection; -using Newtonsoft.Json; -using Shouldly; -using Volo.Abp.DependencyInjection; -using Volo.Abp.Json.Newtonsoft; -using Volo.Abp.Json.SystemTextJson; -using Xunit; -using JsonSerializer = Newtonsoft.Json.JsonSerializer; - -namespace Volo.Abp.Json; - -public class AbpHybridJsonSerializer_Tests : AbpJsonTestBase -{ - private readonly IJsonSerializer _jsonSerializer; - - public AbpHybridJsonSerializer_Tests() - { - _jsonSerializer = GetRequiredService(); - } - - protected override void AfterAddApplication(IServiceCollection services) - { - services.Configure(options => - { - options.UnsupportedTypes.Add(); - - options.JsonSerializerOptions.Converters.Add(new SystemTextJsonConverter()); - }); - - services.Configure(options => - { - options.Converters.Add(); - }); - } - - [Fact] - public void NewtonsoftSerialize_Test() - { - var json = _jsonSerializer.Serialize(new MyClass1 - { - Providers = new List - { - new MyClass3() - } - }); - - json.ShouldContain("Newtonsoft"); - } - - [Fact] - public void SystemTextJsonSerialize_Test() - { - var json = _jsonSerializer.Serialize(new MyClass2 - { - Providers = new List - { - new MyClass3() - } - }); - - json.ShouldContain("SystemTextJson"); - } - - [Fact] - public void SystemTextJsonSerialize_With_Dictionary_Test() - { - var json = _jsonSerializer.Serialize(new MyClassWithDictionary - { - Properties = - { - {"A", "AV"}, - {"B", "BV"} - } - }); - - var deserialized = _jsonSerializer.Deserialize(json); - deserialized.Properties.ShouldContain(p => p.Key == "A" && p.Value == "AV"); - deserialized.Properties.ShouldContain(p => p.Key == "B" && p.Value == "BV"); - } - - public class MyClass1 - { - public string Provider { get; set; } - - public List Providers { get; set; } - } - - public class MyClass2 - { - public string Provider { get; set; } - - public List Providers { get; set; } - } - - public class MyClass3 - { - public string Provider { get; set; } - } - - public class MyClassWithDictionary - { - public Dictionary Properties { get; set; } - - public MyClassWithDictionary() - { - Properties = new Dictionary(); - } - } - - class NewtonsoftJsonConverter : JsonConverter, ITransientDependency - { - public override void WriteJson(JsonWriter writer, MyClass1 value, JsonSerializer serializer) - { - value.Provider = "Newtonsoft"; - foreach (var provider in value.Providers) - { - provider.Provider = "Newtonsoft"; - } - - writer.WriteRawValue(JsonConvert.SerializeObject(value)); - } - - public override MyClass1 ReadJson(JsonReader reader, Type objectType, MyClass1 existingValue, bool hasExistingValue, JsonSerializer serializer) - { - return (MyClass1)serializer.Deserialize(reader, objectType); - } - } - - class SystemTextJsonConverter : System.Text.Json.Serialization.JsonConverter, ITransientDependency - { - public override void Write(Utf8JsonWriter writer, MyClass2 value, JsonSerializerOptions options) - { - value.Provider = "SystemTextJson"; - foreach (var provider in value.Providers) - { - provider.Provider = "SystemTextJson"; - } - System.Text.Json.JsonSerializer.Serialize(writer, value); - } - - public override MyClass2 Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - return (MyClass2)System.Text.Json.JsonSerializer.Deserialize(ref reader, typeToConvert); - } - } -} 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 index 21b3fd51bb..f9823e7d65 100644 --- 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 @@ -11,11 +11,11 @@ namespace Volo.Abp.Json; public abstract class AbpSystemTextJsonSerializerProvider_TestBase : AbpJsonTestBase { - protected AbpSystemTextJsonSerializerProvider JsonSerializer; + protected AbpSystemTextJsonSerializer JsonSerializer; public AbpSystemTextJsonSerializerProvider_TestBase() { - JsonSerializer = GetRequiredService(); + JsonSerializer = GetRequiredService(); } public class TestExtensibleObjectClass : ExtensibleObject diff --git a/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/ExtensibleObjectModifiers_Tests.cs b/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/ExtensibleObjectModifiers_Tests.cs index 617301bd6c..820f18b1a2 100644 --- a/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/ExtensibleObjectModifiers_Tests.cs +++ b/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/ExtensibleObjectModifiers_Tests.cs @@ -10,7 +10,7 @@ public class ExtensibleObjectModifiers_Tests : AbpJsonTestBase [Fact] public void Should_Modify_Object() { - var jsonSerializer = GetRequiredService(); + var jsonSerializer = GetRequiredService(); var extensibleObject = jsonSerializer.Deserialize("{\"ExtraProperties\": {\"Test-Key\":\"Test-Value\"}}"); diff --git a/nupkg/common.ps1 b/nupkg/common.ps1 index 9f44b11c6d..a15a8e6b5d 100644 --- a/nupkg/common.ps1 +++ b/nupkg/common.ps1 @@ -192,7 +192,7 @@ $projects = ( "framework/src/Volo.Abp.Http", "framework/src/Volo.Abp.IdentityModel", "framework/src/Volo.Abp.Json", - "framework/src/Volo.Abp.Json.Core", + "framework/src/Volo.Abp.Json.Abstractions", "framework/src/Volo.Abp.Json.Newtonsoft", "framework/src/Volo.Abp.Json.SystemTextJson", "framework/src/Volo.Abp.Ldap", From 46d8b417ac55803691d1998989b35df4e5d01926 Mon Sep 17 00:00:00 2001 From: maliming Date: Wed, 24 Aug 2022 16:55:29 +0800 Subject: [PATCH 011/124] Add `InputDateTimeFormats` and `OutputDateTimeFormat` to `AbpJsonOptions`. Resolve #12338 --- .../Volo/Abp/Json/AbpJsonOptions.cs | 18 ++- ...pCamelCasePropertyNamesContractResolver.cs | 8 +- .../Json/Newtonsoft/AbpDateTimeConverter.cs | 116 ++++++++++++++++++ .../Newtonsoft/AbpDefaultContractResolver.cs | 8 +- .../Newtonsoft/AbpJsonIsoDateTimeConverter.cs | 60 --------- .../JsonConverters/AbpDateTimeConverter.cs | 24 ++-- .../AbpNullableDateTimeConverter.cs | 24 ++-- .../Mvc/Json/JsonResultController_Tests.cs | 2 +- .../Mvc/Json/JsonSerializer_Tests.cs | 2 +- ...pSystemTextJsonSerializerProvider_Tests.cs | 19 ++- 10 files changed, 183 insertions(+), 98 deletions(-) create mode 100644 framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpDateTimeConverter.cs delete mode 100644 framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpJsonIsoDateTimeConverter.cs diff --git a/framework/src/Volo.Abp.Json.Abstractions/Volo/Abp/Json/AbpJsonOptions.cs b/framework/src/Volo.Abp.Json.Abstractions/Volo/Abp/Json/AbpJsonOptions.cs index f7f5370255..043c1081d7 100644 --- a/framework/src/Volo.Abp.Json.Abstractions/Volo/Abp/Json/AbpJsonOptions.cs +++ b/framework/src/Volo.Abp.Json.Abstractions/Volo/Abp/Json/AbpJsonOptions.cs @@ -1,9 +1,21 @@ -namespace Volo.Abp.Json; +using System.Collections.Generic; + +namespace Volo.Abp.Json; public class AbpJsonOptions { /// - /// Used to set default value for the DateTimeFormat. + /// Formats of input JSON date, Empty string means default format. /// - public string DefaultDateTimeFormat { get; set; } + public List InputDateTimeFormats { get; set; } + + /// + /// Format of output json date, Null or empty string means default format. + /// + public string OutputDateTimeFormat { get; set; } + + public AbpJsonOptions() + { + InputDateTimeFormats = new List(); + } } diff --git a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpCamelCasePropertyNamesContractResolver.cs b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpCamelCasePropertyNamesContractResolver.cs index a73213af6c..3e4e5d0121 100644 --- a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpCamelCasePropertyNamesContractResolver.cs +++ b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpCamelCasePropertyNamesContractResolver.cs @@ -9,12 +9,12 @@ namespace Volo.Abp.Json.Newtonsoft; public class AbpCamelCasePropertyNamesContractResolver : CamelCasePropertyNamesContractResolver, ITransientDependency { - private readonly Lazy _dateTimeConverter; + private readonly Lazy _dateTimeConverter; public AbpCamelCasePropertyNamesContractResolver(IServiceProvider serviceProvider) { - _dateTimeConverter = new Lazy( - serviceProvider.GetRequiredService, + _dateTimeConverter = new Lazy( + serviceProvider.GetRequiredService, true ); @@ -28,7 +28,7 @@ public class AbpCamelCasePropertyNamesContractResolver : CamelCasePropertyNamesC { var property = base.CreateProperty(member, memberSerialization); - if (AbpJsonIsoDateTimeConverter.ShouldNormalize(member, property)) + if (AbpDateTimeConverter.ShouldNormalize(member, property)) { property.Converter = _dateTimeConverter.Value; } diff --git a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpDateTimeConverter.cs b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpDateTimeConverter.cs new file mode 100644 index 0000000000..3bd97f7aee --- /dev/null +++ b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpDateTimeConverter.cs @@ -0,0 +1,116 @@ +using System; +using System.Globalization; +using System.Linq; +using System.Reflection; +using Microsoft.Extensions.Options; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Serialization; +using Volo.Abp.Reflection; +using Volo.Abp.Timing; + +namespace Volo.Abp.Json.Newtonsoft; + +public class AbpDateTimeConverter : DateTimeConverterBase +{ + private readonly string _dateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK"; + private readonly DateTimeStyles _dateTimeStyles = DateTimeStyles.RoundtripKind; + private readonly CultureInfo _culture = CultureInfo.InvariantCulture; + private readonly IClock _clock; + private readonly AbpJsonOptions _options; + + public AbpDateTimeConverter(IClock clock, IOptions options) + { + _clock = clock; + _options = options.Value; + } + + public override bool CanConvert(Type objectType) + { + return objectType == typeof(DateTime) || objectType == typeof(DateTime?); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + var nullable = Nullable.GetUnderlyingType(objectType) != null; + if (reader.TokenType == JsonToken.Null) + { + if (!nullable) + { + throw new JsonSerializationException($"Cannot convert null value to {objectType.FullName}."); + } + + return null; + } + + if (reader.TokenType == JsonToken.Date) + { + return _clock.Normalize(reader.Value.To()); + } + + if (reader.TokenType != JsonToken.String) + { + throw new JsonSerializationException($"Unexpected token parsing date. Expected String, got {reader.TokenType}."); + } + + var dateText = reader.Value?.ToString(); + + if (dateText.IsNullOrEmpty() && nullable) + { + return null; + } + + if (_options.InputDateTimeFormats.Any()) + { + foreach (var format in _options.InputDateTimeFormats) + { + if (DateTime.TryParseExact(dateText, format, _culture, _dateTimeStyles, out var d1)) + { + return _clock.Normalize(d1); + } + } + } + + var date = !_dateTimeFormat.IsNullOrEmpty() ? + DateTime.ParseExact(dateText, _dateTimeFormat, _culture, _dateTimeStyles) : + DateTime.Parse(dateText, _culture, _dateTimeStyles); + + return _clock.Normalize(date); + } + + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + if (value != null) + { + value = _clock.Normalize(value.To()); + } + + if (value is DateTime dateTime) + { + if ((_dateTimeStyles & DateTimeStyles.AdjustToUniversal) == DateTimeStyles.AdjustToUniversal || + (_dateTimeStyles & DateTimeStyles.AssumeUniversal) == DateTimeStyles.AssumeUniversal) + { + dateTime = dateTime.ToUniversalTime(); + } + + writer.WriteValue(_options.OutputDateTimeFormat.IsNullOrWhiteSpace() + ? dateTime.ToString(_dateTimeFormat, _culture) + : dateTime.ToString(_options.OutputDateTimeFormat, _culture)); + } + else + { + throw new JsonSerializationException($"Unexpected value when converting date. Expected DateTime or DateTimeOffset, got {value.GetType()}."); + } + } + + internal static bool ShouldNormalize(MemberInfo member, JsonProperty property) + { + if (property.PropertyType != typeof(DateTime) && + property.PropertyType != typeof(DateTime?)) + { + return false; + } + + return ReflectionHelper.GetSingleAttributeOfMemberOrDeclaringTypeOrDefault(member) == null; + } +} diff --git a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpDefaultContractResolver.cs b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpDefaultContractResolver.cs index f39f6af578..131e95d4c2 100644 --- a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpDefaultContractResolver.cs +++ b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpDefaultContractResolver.cs @@ -9,12 +9,12 @@ namespace Volo.Abp.Json.Newtonsoft; public class AbpDefaultContractResolver : DefaultContractResolver, ITransientDependency { - private readonly Lazy _dateTimeConverter; + private readonly Lazy _dateTimeConverter; public AbpDefaultContractResolver(IServiceProvider serviceProvider) { - _dateTimeConverter = new Lazy( - serviceProvider.GetRequiredService, + _dateTimeConverter = new Lazy( + serviceProvider.GetRequiredService, true ); } @@ -23,7 +23,7 @@ public class AbpDefaultContractResolver : DefaultContractResolver, ITransientDep { var property = base.CreateProperty(member, memberSerialization); - if (AbpJsonIsoDateTimeConverter.ShouldNormalize(member, property)) + if (AbpDateTimeConverter.ShouldNormalize(member, property)) { property.Converter = _dateTimeConverter.Value; } diff --git a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpJsonIsoDateTimeConverter.cs b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpJsonIsoDateTimeConverter.cs deleted file mode 100644 index b859688a0d..0000000000 --- a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpJsonIsoDateTimeConverter.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System; -using System.Reflection; -using Microsoft.Extensions.Options; -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; -using Newtonsoft.Json.Serialization; -using Volo.Abp.DependencyInjection; -using Volo.Abp.Reflection; -using Volo.Abp.Timing; - -namespace Volo.Abp.Json.Newtonsoft; - -public class AbpJsonIsoDateTimeConverter : IsoDateTimeConverter, ITransientDependency -{ - private readonly IClock _clock; - - public AbpJsonIsoDateTimeConverter(IClock clock, IOptions abpJsonOptions) - { - _clock = clock; - - if (abpJsonOptions.Value.DefaultDateTimeFormat != null) - { - DateTimeFormat = abpJsonOptions.Value.DefaultDateTimeFormat; - } - } - - public override bool CanConvert(Type objectType) - { - return objectType == typeof(DateTime) || objectType == typeof(DateTime?); - } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - var date = base.ReadJson(reader, objectType, existingValue, serializer) as DateTime?; - - if (date.HasValue) - { - return _clock.Normalize(date.Value); - } - - return null; - } - - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - var date = value as DateTime?; - base.WriteJson(writer, date.HasValue ? _clock.Normalize(date.Value) : value, serializer); - } - - internal static bool ShouldNormalize(MemberInfo member, JsonProperty property) - { - if (property.PropertyType != typeof(DateTime) && - property.PropertyType != typeof(DateTime?)) - { - return false; - } - - return ReflectionHelper.GetSingleAttributeOfMemberOrDeclaringTypeOrDefault(member) == null; - } -} diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpDateTimeConverter.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpDateTimeConverter.cs index 417037e776..366a933d13 100644 --- a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpDateTimeConverter.cs +++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpDateTimeConverter.cs @@ -1,5 +1,6 @@ using System; using System.Globalization; +using System.Linq; using System.Text.Json; using System.Text.Json.Serialization; using Microsoft.Extensions.Options; @@ -21,20 +22,23 @@ public class AbpDateTimeConverter : JsonConverter, ITransientDependenc public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - if (!_options.DefaultDateTimeFormat.IsNullOrWhiteSpace()) + if (_options.InputDateTimeFormats.Any()) { if (reader.TokenType == JsonTokenType.String) { - var s = reader.GetString(); - if (DateTime.TryParseExact(s, _options.DefaultDateTimeFormat, CultureInfo.CurrentUICulture, DateTimeStyles.None, out var d1)) + foreach (var format in _options.InputDateTimeFormats) { - return _clock.Normalize(d1); + var s = reader.GetString(); + if (DateTime.TryParseExact(s, format, CultureInfo.CurrentUICulture, DateTimeStyles.None, out var d1)) + { + return _clock.Normalize(d1); + } } - - throw new JsonException($"'{s}' can't parse to DateTime({_options.DefaultDateTimeFormat})!"); } - - throw new JsonException("Reader's TokenType is not String!"); + else + { + throw new JsonException("Reader's TokenType is not String!"); + } } if (reader.TryGetDateTime(out var d3)) @@ -47,13 +51,13 @@ public class AbpDateTimeConverter : JsonConverter, ITransientDependenc public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options) { - if (_options.DefaultDateTimeFormat.IsNullOrWhiteSpace()) + if (_options.OutputDateTimeFormat.IsNullOrWhiteSpace()) { writer.WriteStringValue(_clock.Normalize(value)); } else { - writer.WriteStringValue(_clock.Normalize(value).ToString(_options.DefaultDateTimeFormat, CultureInfo.CurrentUICulture)); + writer.WriteStringValue(_clock.Normalize(value).ToString(_options.OutputDateTimeFormat, CultureInfo.CurrentUICulture)); } } } diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpNullableDateTimeConverter.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpNullableDateTimeConverter.cs index 8b3459fcce..da5983250d 100644 --- a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpNullableDateTimeConverter.cs +++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpNullableDateTimeConverter.cs @@ -1,5 +1,6 @@ using System; using System.Globalization; +using System.Linq; using System.Text.Json; using System.Text.Json.Serialization; using Microsoft.Extensions.Options; @@ -21,20 +22,23 @@ public class AbpNullableDateTimeConverter : JsonConverter, ITransient public override DateTime? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - if (!_options.DefaultDateTimeFormat.IsNullOrWhiteSpace()) + if (_options.InputDateTimeFormats.Any()) { if (reader.TokenType == JsonTokenType.String) { - var s = reader.GetString(); - if (DateTime.TryParseExact(s, _options.DefaultDateTimeFormat, CultureInfo.CurrentUICulture, DateTimeStyles.None, out var d1)) + foreach (var format in _options.InputDateTimeFormats) { - return _clock.Normalize(d1); + var s = reader.GetString(); + if (DateTime.TryParseExact(s, format, CultureInfo.CurrentUICulture, DateTimeStyles.None, out var d1)) + { + return _clock.Normalize(d1); + } } - - throw new JsonException($"'{s}' can't parse to DateTime({_options.DefaultDateTimeFormat})!"); } - - throw new JsonException("Reader's TokenType is not String!"); + else + { + throw new JsonException("Reader's TokenType is not String!"); + } } if (reader.TryGetDateTime(out var d2)) @@ -53,13 +57,13 @@ public class AbpNullableDateTimeConverter : JsonConverter, ITransient } else { - if (_options.DefaultDateTimeFormat.IsNullOrWhiteSpace()) + if (_options.OutputDateTimeFormat.IsNullOrWhiteSpace()) { writer.WriteStringValue(_clock.Normalize(value.Value)); } else { - writer.WriteStringValue(_clock.Normalize(value.Value).ToString(_options.DefaultDateTimeFormat, CultureInfo.CurrentUICulture)); + writer.WriteStringValue(_clock.Normalize(value.Value).ToString(_options.OutputDateTimeFormat, CultureInfo.CurrentUICulture)); } } } diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Json/JsonResultController_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Json/JsonResultController_Tests.cs index 851ef88db8..e7015313cb 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Json/JsonResultController_Tests.cs +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Json/JsonResultController_Tests.cs @@ -14,7 +14,7 @@ public class JsonResultController_Tests : AspNetCoreMvcTestBase { services.Configure(options => { - options.DefaultDateTimeFormat = "yyyy*MM*dd"; + options.OutputDateTimeFormat = "yyyy*MM*dd"; }); base.ConfigureServices(context, services); diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Json/JsonSerializer_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Json/JsonSerializer_Tests.cs index 2f986c89c3..1613e4bb49 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Json/JsonSerializer_Tests.cs +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Json/JsonSerializer_Tests.cs @@ -21,7 +21,7 @@ public class JsonSerializer_Tests : AspNetCoreMvcTestBase { services.Configure(options => { - options.DefaultDateTimeFormat = "yyyy*MM*dd"; + options.OutputDateTimeFormat = "yyyy*MM*dd"; }); base.ConfigureServices(context, services); 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 index f9823e7d65..f605914d6e 100644 --- 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 @@ -220,7 +220,8 @@ public class AbpSystemTextJsonSerializerProvider_DateTimeFormat_Tests : AbpSyste { services.Configure(options => { - options.DefaultDateTimeFormat = "yyyy*MM*dd"; + options.InputDateTimeFormats.Add("yyyy*MM*dd"); + options.OutputDateTimeFormat = "yyyy*MM*dd HH*mm*ss"; }); } @@ -233,8 +234,12 @@ public class AbpSystemTextJsonSerializerProvider_DateTimeFormat_Tests : AbpSyste file.CreationTime.Month.ShouldBe(11); file.CreationTime.Day.ShouldBe(20); - var newJson = JsonSerializer.Serialize(file); - newJson.ShouldBe(json); + json = JsonSerializer.Serialize(new FileWithDatetime() + { + Name = "abp", + CreationTime = new DateTime(2020, 11, 20, 12, 34, 56) + }); + json.ShouldContain("\"2020*11*20 12*34*56\""); } [Fact] @@ -256,8 +261,12 @@ public class AbpSystemTextJsonSerializerProvider_DateTimeFormat_Tests : AbpSyste file.CreationTime.Value.Month.ShouldBe(11); file.CreationTime.Value.Day.ShouldBe(20); - var newJson = JsonSerializer.Serialize(file); - newJson.ShouldBe(json); + json = JsonSerializer.Serialize(new FileWithDatetime() + { + Name = "abp", + CreationTime = new DateTime(2020, 11, 20, 12, 34, 56) + }); + json.ShouldContain("\"2020*11*20 12*34*56\""); } } From cfa60f3a5f2db0ddd8a944761c3d23ac12d6bc61 Mon Sep 17 00:00:00 2001 From: maliming Date: Thu, 25 Aug 2022 20:09:11 +0800 Subject: [PATCH 012/124] Remove `Newtonsoft` from `feature-management`. --- ...ureManagementApplicationContractsModule.cs | 6 - .../NewtonsoftStringValueTypeJsonConverter.cs | 95 -------------- ...ewtonsoftStringValueJsonConverter_Tests.cs | 16 --- .../StringValueJsonConverter_Tests.cs | 122 ------------------ ...mTextJsonStringValueJsonConverter_Tests.cs | 118 ++++++++++++++++- 5 files changed, 112 insertions(+), 245 deletions(-) delete mode 100644 modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/JsonConverters/NewtonsoftStringValueTypeJsonConverter.cs delete mode 100644 modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/NewtonsoftStringValueJsonConverter_Tests.cs delete mode 100644 modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/StringValueJsonConverter_Tests.cs 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 cfbcf1c95e..b94459dc68 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 @@ -4,7 +4,6 @@ using Volo.Abp.Application; using Volo.Abp.Authorization; using Volo.Abp.FeatureManagement.JsonConverters; using Volo.Abp.Json; -using Volo.Abp.Json.Newtonsoft; using Volo.Abp.Json.SystemTextJson; using Volo.Abp.Modularity; using Volo.Abp.VirtualFileSystem; @@ -32,11 +31,6 @@ public class AbpFeatureManagementApplicationContractsModule : AbpModule contractsOptionsActions.Configure(options); }); - Configure(options => - { - options.Converters.Add(); - }); - Configure(options => { options.JsonSerializerOptions.Converters.AddIfNotContains(new StringValueTypeJsonConverter(contractsOptionsActions.Configure())); diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/JsonConverters/NewtonsoftStringValueTypeJsonConverter.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/JsonConverters/NewtonsoftStringValueTypeJsonConverter.cs deleted file mode 100644 index aa9a913718..0000000000 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/JsonConverters/NewtonsoftStringValueTypeJsonConverter.cs +++ /dev/null @@ -1,95 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using Microsoft.Extensions.Options; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using Volo.Abp.DependencyInjection; -using Volo.Abp.Validation.StringValues; - -namespace Volo.Abp.FeatureManagement.JsonConverters; - -public class NewtonsoftStringValueTypeJsonConverter : JsonConverter, ITransientDependency -{ - public override bool CanWrite => false; - - protected readonly AbpFeatureManagementApplicationContractsOptions Options; - - public NewtonsoftStringValueTypeJsonConverter(IOptions options) - { - Options = options.Value; - } - - public override bool CanConvert(Type objectType) - { - return objectType == typeof(IStringValueType); - } - - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - throw new NotImplementedException("This method should not be called to write (since CanWrite is false)."); - } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - if (reader.TokenType != JsonToken.StartObject) - { - return null; - } - - var jsonObject = JObject.Load(reader); - - var stringValue = CreateStringValueTypeByName(jsonObject, jsonObject["name"].ToString()); - foreach (var o in serializer.Deserialize>( - new JsonTextReader(new StringReader(jsonObject["properties"].ToString())))) - { - stringValue[o.Key] = o.Value; - } - - stringValue.Validator = CreateValueValidatorByName(jsonObject["validator"], jsonObject["validator"]["name"].ToString()); - foreach (var o in serializer.Deserialize>( - new JsonTextReader(new StringReader(jsonObject["validator"]["properties"].ToString())))) - { - stringValue.Validator[o.Key] = o.Value; - } - - return stringValue; - } - - protected virtual IStringValueType CreateStringValueTypeByName(JObject jObject, string name) - { - if (name == "SelectionStringValueType") - { - var selectionStringValueType = new SelectionStringValueType(); - if (jObject["itemSource"].HasValues) - { - selectionStringValueType.ItemSource = new StaticSelectionStringValueItemSource(jObject["itemSource"]["items"] - .Select(item => new LocalizableSelectionStringValueItem() - { - Value = item["value"].ToString(), - DisplayText = new LocalizableStringInfo(item["displayText"]["resourceName"].ToString(), item["displayText"]["name"].ToString()) - }).ToArray()); - } - - return selectionStringValueType; - } - - return name switch - { - "FreeTextStringValueType" => new FreeTextStringValueType(), - "ToggleStringValueType" => new ToggleStringValueType(), - _ => throw new ArgumentException($"{nameof(IStringValueType)} named {name} was not found!") - }; - } - - protected virtual IValueValidator CreateValueValidatorByName(JToken jObject, string name) - { - foreach (var factory in Options.ValueValidatorFactory.Where(factory => factory.CanCreate(name))) - { - return factory.Create(); - } - - throw new ArgumentException($"{nameof(IValueValidator)} named {name} was cannot be created!"); - } -} diff --git a/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/NewtonsoftStringValueJsonConverter_Tests.cs b/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/NewtonsoftStringValueJsonConverter_Tests.cs deleted file mode 100644 index 4a8a1a36be..0000000000 --- a/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/NewtonsoftStringValueJsonConverter_Tests.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Microsoft.Extensions.DependencyInjection; -using Volo.Abp.Json; -using Volo.Abp.Json.SystemTextJson; - -namespace Volo.Abp.FeatureManagement; - -public class NewtonsoftStringValueJsonConverter_Tests : StringValueJsonConverter_Tests -{ - protected override void AfterAddApplication(IServiceCollection services) - { - services.PreConfigure(options => - { - options.Providers.Remove(); - }); - } -} diff --git a/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/StringValueJsonConverter_Tests.cs b/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/StringValueJsonConverter_Tests.cs deleted file mode 100644 index 28b8e55052..0000000000 --- a/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/StringValueJsonConverter_Tests.cs +++ /dev/null @@ -1,122 +0,0 @@ -using System; -using System.Collections.Generic; -using Microsoft.Extensions.DependencyInjection; -using Shouldly; -using Volo.Abp.FeatureManagement.JsonConverters; -using Volo.Abp.Json; -using Volo.Abp.Validation.StringValues; -using Xunit; - -namespace Volo.Abp.FeatureManagement; - -public abstract class StringValueJsonConverter_Tests : FeatureManagementApplicationTestBase -{ - private readonly IJsonSerializer _jsonSerializer; - - public StringValueJsonConverter_Tests() - { - _jsonSerializer = GetRequiredService(); - } - - protected override void BeforeAddApplication(IServiceCollection services) - { - services.PreConfigure(options => - { - options.ValueValidatorFactory.Add(new ValueValidatorFactory("URL")); - }); - - base.BeforeAddApplication(services); - } - - [Fact] - public void Should_Serialize_And_Deserialize() - { - var featureListDto = new GetFeatureListResultDto - { - Groups = new List - { - new FeatureGroupDto - { - Name = "MyGroup", - DisplayName = "MyGroup", - Features = new List - { - new FeatureDto - { - ValueType = new FreeTextStringValueType - { - Validator = new BooleanValueValidator() - } - }, - new FeatureDto - { - ValueType = new SelectionStringValueType - { - ItemSource = new StaticSelectionStringValueItemSource( - new LocalizableSelectionStringValueItem - { - Value = "TestValue", - DisplayText = new LocalizableStringInfo("TestResourceName", "TestName") - }), - Validator = new AlwaysValidValueValidator() - } - }, - new FeatureDto - { - ValueType = new ToggleStringValueType - { - Validator = new NumericValueValidator - { - MaxValue = 1000, - MinValue = 10 - } - } - }, - new FeatureDto - { - Provider = new FeatureProviderDto - { - Name = "FeatureName", - Key = "FeatureKey" - } - }, - new FeatureDto - { - ValueType = new FreeTextStringValueType - { - Validator = new UrlValueValidator("https") - } - } - } - } - } - }; - - var serialized = _jsonSerializer.Serialize(featureListDto, indented: true); - - var featureListDto2 = _jsonSerializer.Deserialize(serialized); - - featureListDto2.ShouldNotBeNull(); - featureListDto2.Groups[0].Features[0].ValueType.ShouldBeOfType(); - featureListDto2.Groups[0].Features[0].ValueType.Validator.ShouldBeOfType(); - - featureListDto2.Groups[0].Features[1].ValueType.ShouldBeOfType(); - featureListDto2.Groups[0].Features[1].ValueType.Validator.ShouldBeOfType(); - featureListDto2.Groups[0].Features[1].ValueType.As().ItemSource.Items.ShouldBeOfType(); - featureListDto2.Groups[0].Features[1].ValueType.As().ItemSource.Items.ShouldContain(x => - x.Value == "TestValue" && x.DisplayText.ResourceName == "TestResourceName" && - x.DisplayText.Name == "TestName"); - - featureListDto2.Groups[0].Features[2].ValueType.ShouldBeOfType(); - featureListDto2.Groups[0].Features[2].ValueType.Validator.ShouldBeOfType(); - featureListDto2.Groups[0].Features[2].ValueType.Validator.As().MaxValue.ShouldBe(1000); - featureListDto2.Groups[0].Features[2].ValueType.Validator.As().MinValue.ShouldBe(10); - - featureListDto2.Groups[0].Features[3].Provider.Name.ShouldBe("FeatureName"); - featureListDto2.Groups[0].Features[3].Provider.Key.ShouldBe("FeatureKey"); - - featureListDto2.Groups[0].Features[4].ValueType.ShouldBeOfType(); - featureListDto2.Groups[0].Features[4].ValueType.Validator.ShouldBeOfType(); - featureListDto2.Groups[0].Features[4].ValueType.Validator.As().Scheme.ShouldBe("https"); - } -} diff --git a/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/SystemTextJsonStringValueJsonConverter_Tests.cs b/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/SystemTextJsonStringValueJsonConverter_Tests.cs index e51f9885ac..828d5b3814 100644 --- a/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/SystemTextJsonStringValueJsonConverter_Tests.cs +++ b/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/SystemTextJsonStringValueJsonConverter_Tests.cs @@ -1,16 +1,122 @@ -using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Generic; +using Microsoft.Extensions.DependencyInjection; +using Shouldly; +using Volo.Abp.FeatureManagement.JsonConverters; using Volo.Abp.Json; -using Volo.Abp.Json.Newtonsoft; +using Volo.Abp.Validation.StringValues; +using Xunit; namespace Volo.Abp.FeatureManagement; -public class SystemTextJsonStringValueJsonConverter_Tests : StringValueJsonConverter_Tests +public class SystemTextJsonStringValueJsonConverter_Tests : FeatureManagementApplicationTestBase { - protected override void AfterAddApplication(IServiceCollection services) + private readonly IJsonSerializer _jsonSerializer; + + public SystemTextJsonStringValueJsonConverter_Tests() + { + _jsonSerializer = GetRequiredService(); + } + + protected override void BeforeAddApplication(IServiceCollection services) { - services.PreConfigure(options => + services.PreConfigure(options => { - options.Providers.Remove(); + options.ValueValidatorFactory.Add(new ValueValidatorFactory("URL")); }); + + base.BeforeAddApplication(services); + } + + [Fact] + public void Should_Serialize_And_Deserialize() + { + var featureListDto = new GetFeatureListResultDto + { + Groups = new List + { + new FeatureGroupDto + { + Name = "MyGroup", + DisplayName = "MyGroup", + Features = new List + { + new FeatureDto + { + ValueType = new FreeTextStringValueType + { + Validator = new BooleanValueValidator() + } + }, + new FeatureDto + { + ValueType = new SelectionStringValueType + { + ItemSource = new StaticSelectionStringValueItemSource( + new LocalizableSelectionStringValueItem + { + Value = "TestValue", + DisplayText = new LocalizableStringInfo("TestResourceName", "TestName") + }), + Validator = new AlwaysValidValueValidator() + } + }, + new FeatureDto + { + ValueType = new ToggleStringValueType + { + Validator = new NumericValueValidator + { + MaxValue = 1000, + MinValue = 10 + } + } + }, + new FeatureDto + { + Provider = new FeatureProviderDto + { + Name = "FeatureName", + Key = "FeatureKey" + } + }, + new FeatureDto + { + ValueType = new FreeTextStringValueType + { + Validator = new UrlValueValidator("https") + } + } + } + } + } + }; + + var serialized = _jsonSerializer.Serialize(featureListDto, indented: true); + + var featureListDto2 = _jsonSerializer.Deserialize(serialized); + + featureListDto2.ShouldNotBeNull(); + featureListDto2.Groups[0].Features[0].ValueType.ShouldBeOfType(); + featureListDto2.Groups[0].Features[0].ValueType.Validator.ShouldBeOfType(); + + featureListDto2.Groups[0].Features[1].ValueType.ShouldBeOfType(); + featureListDto2.Groups[0].Features[1].ValueType.Validator.ShouldBeOfType(); + featureListDto2.Groups[0].Features[1].ValueType.As().ItemSource.Items.ShouldBeOfType(); + featureListDto2.Groups[0].Features[1].ValueType.As().ItemSource.Items.ShouldContain(x => + x.Value == "TestValue" && x.DisplayText.ResourceName == "TestResourceName" && + x.DisplayText.Name == "TestName"); + + featureListDto2.Groups[0].Features[2].ValueType.ShouldBeOfType(); + featureListDto2.Groups[0].Features[2].ValueType.Validator.ShouldBeOfType(); + featureListDto2.Groups[0].Features[2].ValueType.Validator.As().MaxValue.ShouldBe(1000); + featureListDto2.Groups[0].Features[2].ValueType.Validator.As().MinValue.ShouldBe(10); + + featureListDto2.Groups[0].Features[3].Provider.Name.ShouldBe("FeatureName"); + featureListDto2.Groups[0].Features[3].Provider.Key.ShouldBe("FeatureKey"); + + featureListDto2.Groups[0].Features[4].ValueType.ShouldBeOfType(); + featureListDto2.Groups[0].Features[4].ValueType.Validator.ShouldBeOfType(); + featureListDto2.Groups[0].Features[4].ValueType.Validator.As().Scheme.ShouldBe("https"); } } From 291c07155da9920e01f58684f87122750d708b0b Mon Sep 17 00:00:00 2001 From: maliming Date: Fri, 26 Aug 2022 11:27:18 +0800 Subject: [PATCH 013/124] Add `AbpIgnorePropertiesModifiers`. --- ...ystemTextJsonSerializerModifiersOptions.cs | 2 +- .../Modifiers/AbpIgnorePropertiesModifiers.cs | 26 +++++++ ... => AbpIncludeExtraPropertiesModifiers.cs} | 13 ++-- ...AbpIncludeNonPublicPropertiesModifiers.cs} | 15 ++-- .../AbpIgnorePropertiesModifiers_Tests.cs | 73 +++++++++++++++++++ ...cludeNonPublicPropertiesModifiers_Tests.cs | 61 ++++++++++++++++ .../Volo/Abp/Json/ExtensibleObject_Tests.cs | 2 +- 7 files changed, 179 insertions(+), 13 deletions(-) create mode 100644 framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpIgnorePropertiesModifiers.cs rename framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/{IncludeExtraPropertiesModifiers.cs => AbpIncludeExtraPropertiesModifiers.cs} (54%) rename framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/{IncludeNonPublicPropertiesModifiers.cs => AbpIncludeNonPublicPropertiesModifiers.cs} (61%) create mode 100644 framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpIgnorePropertiesModifiers_Tests.cs create mode 100644 framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpIncludeNonPublicPropertiesModifiers_Tests.cs diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerModifiersOptions.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerModifiersOptions.cs index efc0a6a883..5b59a7583d 100644 --- a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerModifiersOptions.cs +++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpSystemTextJsonSerializerModifiersOptions.cs @@ -14,7 +14,7 @@ public class AbpSystemTextJsonSerializerModifiersOptions { Modifiers = new List> { - IncludeExtraPropertiesModifiers.Modify, + AbpIncludeExtraPropertiesModifiers.Modify, }; } } diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpIgnorePropertiesModifiers.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpIgnorePropertiesModifiers.cs new file mode 100644 index 0000000000..6eff57bfbf --- /dev/null +++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpIgnorePropertiesModifiers.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq.Expressions; +using System.Text.Json.Serialization.Metadata; + +namespace Volo.Abp.Json.SystemTextJson.Modifiers; + +public class AbpIgnorePropertiesModifiers + where TClass : class +{ + private Expression> _propertySelector; + + public Action CreateModifyAction(Expression> propertySelector) + { + _propertySelector = propertySelector; + return Modify; + } + + public void Modify(JsonTypeInfo jsonTypeInfo) + { + if (jsonTypeInfo.Type == typeof(TClass)) + { + jsonTypeInfo.Properties.RemoveAll(x => x.Name == _propertySelector.Body.As().Member.Name); + } + } +} diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/IncludeExtraPropertiesModifiers.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpIncludeExtraPropertiesModifiers.cs similarity index 54% rename from framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/IncludeExtraPropertiesModifiers.cs rename to framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpIncludeExtraPropertiesModifiers.cs index a3168fa76f..edb0b121b7 100644 --- a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/IncludeExtraPropertiesModifiers.cs +++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpIncludeExtraPropertiesModifiers.cs @@ -1,19 +1,22 @@ using System; using System.Linq; +using System.Reflection; using System.Text.Json.Serialization.Metadata; using Volo.Abp.Data; using Volo.Abp.ObjectExtending; namespace Volo.Abp.Json.SystemTextJson.Modifiers; -public static class IncludeExtraPropertiesModifiers +public static class AbpIncludeExtraPropertiesModifiers { public static void Modify(JsonTypeInfo jsonTypeInfo) { - var propertyJsonInfo = jsonTypeInfo.Properties.FirstOrDefault(x => - x.PropertyType == typeof(ExtraPropertyDictionary) && - x.Name.Equals(nameof(ExtensibleObject.ExtraProperties), StringComparison.OrdinalIgnoreCase) && - x.Set == null); + var propertyJsonInfo = jsonTypeInfo.Properties + .Where(x => x.AttributeProvider != null && x.AttributeProvider is MemberInfo) + .FirstOrDefault(x => + x.PropertyType == typeof(ExtraPropertyDictionary) && + x.AttributeProvider.As().Name == nameof(ExtensibleObject.ExtraProperties) && + x.Set == null); if (propertyJsonInfo != null) { diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/IncludeNonPublicPropertiesModifiers.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpIncludeNonPublicPropertiesModifiers.cs similarity index 61% rename from framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/IncludeNonPublicPropertiesModifiers.cs rename to framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpIncludeNonPublicPropertiesModifiers.cs index fcca1d672c..2005bb4f5e 100644 --- a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/IncludeNonPublicPropertiesModifiers.cs +++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpIncludeNonPublicPropertiesModifiers.cs @@ -1,17 +1,19 @@ using System; using System.Linq; +using System.Linq.Expressions; +using System.Reflection; using System.Text.Json.Serialization.Metadata; namespace Volo.Abp.Json.SystemTextJson.Modifiers; -public class IncludeNonPublicPropertiesModifiers +public class AbpIncludeNonPublicPropertiesModifiers where TClass : class { - private string _propertyName; + private Expression> _propertySelector; - public Action CreateModifyAction(string propertyName) + public Action CreateModifyAction(Expression> propertySelector) { - _propertyName = propertyName; + _propertySelector = propertySelector; return Modify; } @@ -19,10 +21,11 @@ public class IncludeNonPublicPropertiesModifiers { if (jsonTypeInfo.Type == typeof(TClass)) { - var propertyJsonInfo = jsonTypeInfo.Properties.FirstOrDefault(x => x.Name.Equals(_propertyName, StringComparison.OrdinalIgnoreCase) && x.Set == null); + var propertyName = _propertySelector.Body.As().Member.Name; + var propertyJsonInfo = jsonTypeInfo.Properties.FirstOrDefault(x => x.Name == propertyName && x.Set == null); if (propertyJsonInfo != null) { - var propertyInfo = typeof(TClass).GetProperty(_propertyName); + var propertyInfo = typeof(TClass).GetProperty(propertyName, BindingFlags.NonPublic); if (propertyInfo != null) { var jsonPropertyInfo = jsonTypeInfo.CreateJsonPropertyInfo(typeof(TProperty), propertyJsonInfo.Name); diff --git a/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpIgnorePropertiesModifiers_Tests.cs b/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpIgnorePropertiesModifiers_Tests.cs new file mode 100644 index 0000000000..138ffd46a7 --- /dev/null +++ b/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpIgnorePropertiesModifiers_Tests.cs @@ -0,0 +1,73 @@ +using System.Collections.Generic; +using Microsoft.Extensions.DependencyInjection; +using Shouldly; +using Volo.Abp.Json.SystemTextJson; +using Volo.Abp.Json.SystemTextJson.Modifiers; +using Xunit; + +namespace Volo.Abp.Json; + +public class AbpIgnorePropertiesModifiers_Tests : AbpJsonTestBase +{ + private readonly IJsonSerializer _jsonSerializer; + + public AbpIgnorePropertiesModifiers_Tests() + { + _jsonSerializer = GetRequiredService(); + } + + protected override void AfterAddApplication(IServiceCollection services) + { + services.Configure(options => + { + options.Modifiers.Add(new AbpIgnorePropertiesModifiers>().CreateModifyAction(x => x.BarDtos)); + options.Modifiers.Add(new AbpIgnorePropertiesModifiers().CreateModifyAction(x => x.Id)); + }); + + base.AfterAddApplication(services); + } + + [Fact] + public void Test() + { + var json = _jsonSerializer.Serialize(new FooDto() + { + Name = "foo", + BarDtos = new List + { + new BarDto + { + Name = "bar1" + }, + new BarDto + { + Name = "bar2" + } + } + }); + + json.ShouldNotContain("bar"); + + json = _jsonSerializer.Serialize(new BarDto() + { + Id = "id", + Name = "bar" + }); + + json.ShouldNotContain("id"); + } + + class FooDto + { + public string Name { get; set; } + + public List BarDtos { get; set; } + } + + class BarDto + { + public string Id { get; set; } + + public string Name { get; set; } + } +} diff --git a/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpIncludeNonPublicPropertiesModifiers_Tests.cs b/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpIncludeNonPublicPropertiesModifiers_Tests.cs new file mode 100644 index 0000000000..d05ab2dfa0 --- /dev/null +++ b/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpIncludeNonPublicPropertiesModifiers_Tests.cs @@ -0,0 +1,61 @@ +using Microsoft.Extensions.DependencyInjection; +using Shouldly; +using Volo.Abp.Json.SystemTextJson; +using Volo.Abp.Json.SystemTextJson.Modifiers; +using Xunit; + +namespace Volo.Abp.Json; + +public class AbpIncludeNonPublicPropertiesModifiers_Tests : AbpJsonTestBase +{ + private readonly IJsonSerializer _jsonSerializer; + + public AbpIncludeNonPublicPropertiesModifiers_Tests() + { + _jsonSerializer = GetRequiredService(); + } + + protected override void AfterAddApplication(IServiceCollection services) + { + services.Configure(options => + { + options.Modifiers.Add(new AbpIncludeNonPublicPropertiesModifiers().CreateModifyAction(x => x.Name)); + options.Modifiers.Add(new AbpIncludeNonPublicPropertiesModifiers().CreateModifyAction(x => x.Age)); + }); + + base.AfterAddApplication(services); + } + + [Fact] + public void Test() + { + var json = _jsonSerializer.Serialize(new NonPublicPropertiesClass() + { + Id = "id" + }); + + json.ShouldContain("id"); + json.ShouldContain("name"); + json.ShouldContain("age"); + + var obj = _jsonSerializer.Deserialize(json); + obj.Id.ShouldBe("id"); + obj.Name.ShouldBe("name"); + obj.Age.ShouldBe("age"); + } + + class NonPublicPropertiesClass + { + public string Id { get; set; } + + public string Name { get; private set; } + + public string Age { get; protected set; } + + public NonPublicPropertiesClass() + { + Name = "name"; + Age = "age"; + } + } +} diff --git a/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/ExtensibleObject_Tests.cs b/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/ExtensibleObject_Tests.cs index bdd41f20b6..a5bcb723db 100644 --- a/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/ExtensibleObject_Tests.cs +++ b/framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/ExtensibleObject_Tests.cs @@ -7,7 +7,7 @@ using Xunit; namespace Volo.Abp.Json; -public class ExtensibleObject_Tests: AbpJsonTestBase +public class ExtensibleObject_Tests : AbpJsonTestBase { private readonly IJsonSerializer _jsonSerializer; From f99398b7c00053c0f051b7b56c4f50986ba2ef52 Mon Sep 17 00:00:00 2001 From: maliming Date: Fri, 26 Aug 2022 13:16:08 +0800 Subject: [PATCH 014/124] Fix unit test. --- .../SystemTextJson/Modifiers/AbpIgnorePropertiesModifiers.cs | 5 ++++- .../Modifiers/AbpIncludeExtraPropertiesModifiers.cs | 2 +- .../Modifiers/AbpIncludeNonPublicPropertiesModifiers.cs | 5 ++++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpIgnorePropertiesModifiers.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpIgnorePropertiesModifiers.cs index 6eff57bfbf..27a50395bf 100644 --- a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpIgnorePropertiesModifiers.cs +++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpIgnorePropertiesModifiers.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq.Expressions; +using System.Reflection; using System.Text.Json.Serialization.Metadata; namespace Volo.Abp.Json.SystemTextJson.Modifiers; @@ -20,7 +21,9 @@ public class AbpIgnorePropertiesModifiers { if (jsonTypeInfo.Type == typeof(TClass)) { - jsonTypeInfo.Properties.RemoveAll(x => x.Name == _propertySelector.Body.As().Member.Name); + jsonTypeInfo.Properties.RemoveAll( + x => x.AttributeProvider is MemberInfo memberInfo && + memberInfo.Name == _propertySelector.Body.As().Member.Name); } } } diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpIncludeExtraPropertiesModifiers.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpIncludeExtraPropertiesModifiers.cs index edb0b121b7..d692c358eb 100644 --- a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpIncludeExtraPropertiesModifiers.cs +++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpIncludeExtraPropertiesModifiers.cs @@ -12,7 +12,7 @@ public static class AbpIncludeExtraPropertiesModifiers public static void Modify(JsonTypeInfo jsonTypeInfo) { var propertyJsonInfo = jsonTypeInfo.Properties - .Where(x => x.AttributeProvider != null && x.AttributeProvider is MemberInfo) + .Where(x => x.AttributeProvider is MemberInfo) .FirstOrDefault(x => x.PropertyType == typeof(ExtraPropertyDictionary) && x.AttributeProvider.As().Name == nameof(ExtensibleObject.ExtraProperties) && diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpIncludeNonPublicPropertiesModifiers.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpIncludeNonPublicPropertiesModifiers.cs index 2005bb4f5e..3721c3ffcd 100644 --- a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpIncludeNonPublicPropertiesModifiers.cs +++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpIncludeNonPublicPropertiesModifiers.cs @@ -22,7 +22,10 @@ public class AbpIncludeNonPublicPropertiesModifiers if (jsonTypeInfo.Type == typeof(TClass)) { var propertyName = _propertySelector.Body.As().Member.Name; - var propertyJsonInfo = jsonTypeInfo.Properties.FirstOrDefault(x => x.Name == propertyName && x.Set == null); + var propertyJsonInfo = jsonTypeInfo.Properties.FirstOrDefault(x => + x.AttributeProvider is MemberInfo memberInfo && + memberInfo.Name == propertyName && + x.Set == null); if (propertyJsonInfo != null) { var propertyInfo = typeof(TClass).GetProperty(propertyName, BindingFlags.NonPublic); From c22afaadd60f1f128315bc10eb4bbf741963b9ef Mon Sep 17 00:00:00 2001 From: maliming Date: Fri, 26 Aug 2022 16:05:27 +0800 Subject: [PATCH 015/124] Update JSON.md --- docs/en/JSON.md | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/docs/en/JSON.md b/docs/en/JSON.md index 29e93007af..d8979945a7 100644 --- a/docs/en/JSON.md +++ b/docs/en/JSON.md @@ -4,7 +4,7 @@ The ABP Framework provides an abstraction to work with JSON. Having such an abst * You can write library independent code. Therefore, you can change the underlying library with the minimum effort and code change. * You can use the predefined converters defined in the ABP without worrying about the underlying library's internal details. -> The JSON serialization system is implemented with the [Volo.Abp.Json](https://www.nuget.org/packages/Volo.Abp.Json) NuGet package. Most of the time, you don't need to manually [install it](https://abp.io/package-detail/Volo.Abp.Json) since it comes pre-installed with the [application startup template](Startup-Templates/Application.md). +> The JSON serialization system is implemented with the [Volo.Abp.Json](https://www.nuget.org/packages/Volo.Abp.Json) NuGet package([Volo.Abp.Json.SystemTextJson](https://www.nuget.org/packages/Volo.Abp.Json.SystemTextJson) is the default implementation). Most of the time, you don't need to manually [install it](https://abp.io/package-detail/Volo.Abp.Json) since it comes pre-installed with the [application startup template](Startup-Templates/Application.md). ## IJsonSerializer @@ -45,16 +45,24 @@ public class ProductManager `AbpJsonOptions` type provides options for the JSON operations in the ABP Framework. Properties: -* **DefaultDateTimeFormat(`string`)**: Default `DateTime` format. -* **UseHybridSerializer(`bool`)**: True by default. Boolean field indicating whether the ABP Framework uses the hybrid approach or not. If the field is true, it will try to use `System.Json.Text` to handle JSON if it can otherwise use the `Newtonsoft.Json.` -* **Providers(`ITypeList`)**: List of JSON serializer providers implementing the `IJsonSerializerProvider` interface. You can create and add custom serializers to the list, and the ABP Framework uses them automatically. When the `Serialize` or `Deserialize` method is called on the `IJsonSerializer` interface, the ABP Framework calls the `CanHandle` methods of the given providers in reverse order and uses the first provider that returns `true` to do the JSON operation. +* **InputDateTimeFormats(`List`)**: Formats of input JSON date, Empty string means default format. You can provide multiple formats to parse the date. +* **OutputDateTimeFormat(`bool`)**: Format of output json date, Null or empty string means default format. + +## System Text Json ### AbpSystemTextJsonSerializerOptions -`AbpSystemTextJsonSerializerOptions` provides options for `System.Text.Json` usage. +- **JsonSerializerOptions(`System.Text.Json.JsonSerializerOptions`)**: Global options for System.Text.Json library operations. See [here](https://docs.microsoft.com/en-us/dotnet/api/system.text.json.jsonserializeroptions) for reference. -Properties: +### AbpSystemTextJsonSerializerModifiersOptions -- **JsonSerializerOptions(`System.Text.Json.JsonSerializerOptions`)**: Global options for System.Text.Json library operations. See [here](https://docs.microsoft.com/en-us/dotnet/api/system.text.json.jsonserializeroptions) for reference. -- **UnsupportedTypes(`ITypeList`)**: List of the unsupported types. You can add types of the unsupported types to the list and, the hybrid JSON serializer automatically uses the `Newtonsoft.Json` library instead of `System.Text.Json`. +- **Modifiers(`List>`)**: Configure `Modifiers` of `DefaultJsonTypeInfoResolver`. See [here](https://devblogs.microsoft.com/dotnet/announcing-dotnet-7-preview-6/#json-contract-customization) for reference. + + +## Newtonsoft + +Add [Volo.Abp.Json.Newtonsoft](https://www.nuget.org/packages/Volo.Abp.Json.Newtonsoft) pcakge and `AbpJsonNewtonsoftModule` to replace the `System Text Json`. + +#### AbpNewtonsoftJsonSerializerOptions +- **JsonSerializerSettings(`Newtonsoft.Json.JsonSerializerSettings`)**: Global options for Newtonsoft library operations. See [here](https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_JsonSerializerSettings.htm) for reference. From 5537d24e874fc70bf5c3ceb67a57fe5759c53ca7 Mon Sep 17 00:00:00 2001 From: maliming Date: Thu, 15 Sep 2022 10:29:23 +0800 Subject: [PATCH 016/124] Resolve merge conflicts. --- .../Volo.Abp.FeatureManagement.Domain.Shared.csproj | 2 +- .../AbpFeatureManagementDomainSharedModule.cs | 13 ++----------- .../FeatureGroupDefinitionRecord.cs | 2 +- .../SystemTextJsonStringValueJsonConverter_Tests.cs | 2 +- 4 files changed, 5 insertions(+), 14 deletions(-) diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo.Abp.FeatureManagement.Domain.Shared.csproj b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo.Abp.FeatureManagement.Domain.Shared.csproj index 21f8595cf7..14f93d3db7 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo.Abp.FeatureManagement.Domain.Shared.csproj +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo.Abp.FeatureManagement.Domain.Shared.csproj @@ -16,7 +16,7 @@ - + diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/AbpFeatureManagementDomainSharedModule.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/AbpFeatureManagementDomainSharedModule.cs index 5d924f1457..3d47bfbde8 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/AbpFeatureManagementDomainSharedModule.cs +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/AbpFeatureManagementDomainSharedModule.cs @@ -1,10 +1,6 @@ -using System.Collections.Generic; -using System.Linq; -using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection; using Volo.Abp.FeatureManagement.JsonConverters; using Volo.Abp.FeatureManagement.Localization; -using Volo.Abp.Json; -using Volo.Abp.Json.Newtonsoft; using Volo.Abp.Json.SystemTextJson; using Volo.Abp.Localization; using Volo.Abp.Localization.ExceptionHandling; @@ -17,7 +13,7 @@ namespace Volo.Abp.FeatureManagement; [DependsOn( typeof(AbpValidationModule), - typeof(AbpJsonModule) + typeof(AbpJsonSystemTextJsonModule) )] public class AbpFeatureManagementDomainSharedModule : AbpModule { @@ -42,11 +38,6 @@ public class AbpFeatureManagementDomainSharedModule : AbpModule options.MapCodeNamespace("Volo.Abp.FeatureManagement", typeof(AbpFeatureManagementResource)); }); - Configure(options => - { - options.Converters.Add(); - }); - var valueValidatorFactoryOptions = context.Services.GetPreConfigureActions(); Configure(options => { diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/FeatureGroupDefinitionRecord.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/FeatureGroupDefinitionRecord.cs index c40f74c2cd..677f055f3e 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/FeatureGroupDefinitionRecord.cs +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/FeatureGroupDefinitionRecord.cs @@ -1,5 +1,5 @@ using System; -using Newtonsoft.Json; +using System.Text.Json.Serialization; using Volo.Abp.Data; using Volo.Abp.Domain.Entities; diff --git a/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/SystemTextJsonStringValueJsonConverter_Tests.cs b/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/SystemTextJsonStringValueJsonConverter_Tests.cs index 828d5b3814..0517210579 100644 --- a/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/SystemTextJsonStringValueJsonConverter_Tests.cs +++ b/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/SystemTextJsonStringValueJsonConverter_Tests.cs @@ -20,7 +20,7 @@ public class SystemTextJsonStringValueJsonConverter_Tests : FeatureManagementApp protected override void BeforeAddApplication(IServiceCollection services) { - services.PreConfigure(options => + services.PreConfigure(options => { options.ValueValidatorFactory.Add(new ValueValidatorFactory("URL")); }); From 5065c5714e6fc8bb2aa5d3e2110b2b12408d8468 Mon Sep 17 00:00:00 2001 From: maliming Date: Mon, 26 Sep 2022 15:29:09 +0800 Subject: [PATCH 017/124] Update JsonAuditSerializer.cs --- .../Volo/Abp/Auditing/JsonAuditSerializer.cs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/JsonAuditSerializer.cs b/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/JsonAuditSerializer.cs index 9d8c4248e6..5f64c58eed 100644 --- a/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/JsonAuditSerializer.cs +++ b/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/JsonAuditSerializer.cs @@ -38,14 +38,13 @@ public class JsonAuditSerializer : IAuditSerializer, ITransientDependency { jsonTypeInfo => { - if (Options.IgnoredTypes.Any(ignoredType => ignoredType.IsAssignableFrom(jsonTypeInfo.Type))) + if (Options.IgnoredTypes.Any(ignoredType => ignoredType.IsAssignableFrom(jsonTypeInfo.Type)) || + jsonTypeInfo.Type.GetCustomAttributes(typeof(DisableAuditingAttribute), false).Any()) { - jsonTypeInfo.Properties.Clear(); - } - - if (jsonTypeInfo.Type.GetCustomAttributes(typeof(DisableAuditingAttribute), false).Any()) - { - jsonTypeInfo.Properties.Clear(); + if (jsonTypeInfo.Kind == JsonTypeInfoKind.Object) + { + jsonTypeInfo.Properties.Clear(); + } } foreach (var property in jsonTypeInfo.Properties) From 3871cd8414ec39f87abcac09f6a65961548fba19 Mon Sep 17 00:00:00 2001 From: maliming Date: Sat, 1 Oct 2022 15:03:52 +0800 Subject: [PATCH 018/124] Update JsonAuditSerializer_Test.cs --- .../Volo/Abp/Auditing/JsonAuditSerializer_Test.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/test/Volo.Abp.Auditing.Tests/Volo/Abp/Auditing/JsonAuditSerializer_Test.cs b/framework/test/Volo.Abp.Auditing.Tests/Volo/Abp/Auditing/JsonAuditSerializer_Test.cs index ec6244c4d7..2613fe4ba6 100644 --- a/framework/test/Volo.Abp.Auditing.Tests/Volo/Abp/Auditing/JsonAuditSerializer_Test.cs +++ b/framework/test/Volo.Abp.Auditing.Tests/Volo/Abp/Auditing/JsonAuditSerializer_Test.cs @@ -28,7 +28,7 @@ public class JsonAuditSerializer_Test : AbpAuditingTestBase {"input2", new Input2Dto {UserName = "admin", Password = "1q2w3E*", Birthday = DateTime.Now}} }; - var str = GetRequiredService().Serialize(arguments); + var str = GetRequiredService().Serialize(arguments); str.ShouldNotContain("IdCard"); str.ShouldNotContain("1q2w3E*"); From 3b9d8344977b73cab123d5463c699b4a5c9c258c Mon Sep 17 00:00:00 2001 From: maliming Date: Tue, 18 Oct 2022 14:55:43 +0800 Subject: [PATCH 019/124] Update JSON.md --- docs/en/JSON.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/JSON.md b/docs/en/JSON.md index d8979945a7..88877c9e1d 100644 --- a/docs/en/JSON.md +++ b/docs/en/JSON.md @@ -61,7 +61,7 @@ Properties: ## Newtonsoft -Add [Volo.Abp.Json.Newtonsoft](https://www.nuget.org/packages/Volo.Abp.Json.Newtonsoft) pcakge and `AbpJsonNewtonsoftModule` to replace the `System Text Json`. +Add [Volo.Abp.Json.Newtonsoft](https://www.nuget.org/packages/Volo.Abp.Json.Newtonsoft) packge and depends on `AbpJsonNewtonsoftModule` to replace the `System Text Json`. #### AbpNewtonsoftJsonSerializerOptions From 9f32a4b996dab44dcc14b97ae1d797dc6376db1c Mon Sep 17 00:00:00 2001 From: maliming Date: Tue, 18 Oct 2022 16:06:54 +0800 Subject: [PATCH 020/124] Update JSON.md --- docs/en/JSON.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/JSON.md b/docs/en/JSON.md index 88877c9e1d..283690c2e1 100644 --- a/docs/en/JSON.md +++ b/docs/en/JSON.md @@ -46,7 +46,7 @@ public class ProductManager Properties: * **InputDateTimeFormats(`List`)**: Formats of input JSON date, Empty string means default format. You can provide multiple formats to parse the date. -* **OutputDateTimeFormat(`bool`)**: Format of output json date, Null or empty string means default format. +* **OutputDateTimeFormat(`string`)**: Format of output json date, Null or empty string means default format. ## System Text Json From 402ef10aa9c6aa37cb987dba3c7c39b138c32ed5 Mon Sep 17 00:00:00 2001 From: Sean Killeen Date: Tue, 18 Oct 2022 23:22:16 -0400 Subject: [PATCH 021/124] Add GH Action --- .github/workflows/spellcheck.yml | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 .github/workflows/spellcheck.yml diff --git a/.github/workflows/spellcheck.yml b/.github/workflows/spellcheck.yml new file mode 100644 index 0000000000..f7b832e56f --- /dev/null +++ b/.github/workflows/spellcheck.yml @@ -0,0 +1,29 @@ +name: Documentation Checks + +on: + push: + branches: + - dev + paths: + # This ensures the check will only be run when something changes in the docs content + - "docs/en/**/*" # or whatever the path to the markdown / docs files happens to be + pull_request: + branches: + - dev + paths: + - "docs/en/**/*" +jobs: + spellcheck: + name: "Docs: Spellcheck (En)" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + name: Check out the code + - uses: actions/setup-node@v1 + name: Setup node + with: + node-version: "16" + - run: npm install -g cspell + name: Install cSpell + - run: cspell --config ./cSpell.json "docs/en/**/*.md" --no-progress # Update for path to the markdown files + name: Run cSpell From f8d5de21e052a71843829d1c1c6ec7c9aab45bfe Mon Sep 17 00:00:00 2001 From: Sean Killeen Date: Tue, 18 Oct 2022 23:22:20 -0400 Subject: [PATCH 022/124] Add empty cSpell file --- cSpell.json | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 cSpell.json diff --git a/cSpell.json b/cSpell.json new file mode 100644 index 0000000000..034b4e6f9b --- /dev/null +++ b/cSpell.json @@ -0,0 +1,60 @@ +{ + "version": "0.2", + "language": "en", + "words": [ + ], + "ignoreWords": [ + ], + "patterns": [ + { + "name": "Markdown links", + "pattern": "\\((.*)\\)", + "description": "" + }, + { + "name": "Markdown code blocks", + "pattern": "/^(\\s*`{3,}).*[\\s\\S]*?^\\1/gmx", + "description": "Taken from the cSpell example at https://cspell.org/configuration/patterns/#verbose-regular-expressions" + }, + { + "name": "Inline code blocks", + "pattern": "\\`([^\\`\\r\\n]+?)\\`", + "description": "https://stackoverflow.com/questions/41274241/how-to-capture-inline-markdown-code-but-not-a-markdown-code-fence-with-regex" + }, + { + "name": "Link contents", + "pattern": "\\", + "description": "" + }, + { + "name": "Snippet references", + "pattern": "-- snippet:(.*)", + "description": "" + }, + { + "name": "Snippet references 2", + "pattern": "\\<\\[sample:(.*)", + "description": "another kind of snippet reference" + }, + { + "name": "Multi-line code blocks", + "pattern": "/^\\s*```[\\s\\S]*?^\\s*```/gm" + }, + { + "name": "HTML Tags", + "pattern": "<[^>]*>", + "description": "Reference: https://stackoverflow.com/questions/11229831/regular-expression-to-remove-html-tags-from-a-string" + } + ], + "ignoreRegExpList": [ + "Markdown links", + "Markdown code blocks", + "Inline code blocks", + "Link contents", + "Snippet references", + "Snippet references 2", + "Multi-line code blocks", + "HTML Tags" + ], + "ignorePaths": [] + } \ No newline at end of file From a0292ee29d482531d7deca0bee49084bfe8d3294 Mon Sep 17 00:00:00 2001 From: Sean Killeen Date: Tue, 18 Oct 2022 23:24:09 -0400 Subject: [PATCH 023/124] Add known word --- cSpell.json | 100 ++++++++++++++++++++++++++-------------------------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/cSpell.json b/cSpell.json index 034b4e6f9b..980bfd2750 100644 --- a/cSpell.json +++ b/cSpell.json @@ -2,59 +2,59 @@ "version": "0.2", "language": "en", "words": [ + "Blazor" ], - "ignoreWords": [ - ], + "ignoreWords": [], "patterns": [ - { - "name": "Markdown links", - "pattern": "\\((.*)\\)", - "description": "" - }, - { - "name": "Markdown code blocks", - "pattern": "/^(\\s*`{3,}).*[\\s\\S]*?^\\1/gmx", - "description": "Taken from the cSpell example at https://cspell.org/configuration/patterns/#verbose-regular-expressions" - }, - { - "name": "Inline code blocks", - "pattern": "\\`([^\\`\\r\\n]+?)\\`", - "description": "https://stackoverflow.com/questions/41274241/how-to-capture-inline-markdown-code-but-not-a-markdown-code-fence-with-regex" - }, - { - "name": "Link contents", - "pattern": "\\", - "description": "" - }, - { - "name": "Snippet references", - "pattern": "-- snippet:(.*)", - "description": "" - }, - { - "name": "Snippet references 2", - "pattern": "\\<\\[sample:(.*)", - "description": "another kind of snippet reference" - }, - { - "name": "Multi-line code blocks", - "pattern": "/^\\s*```[\\s\\S]*?^\\s*```/gm" - }, - { - "name": "HTML Tags", - "pattern": "<[^>]*>", - "description": "Reference: https://stackoverflow.com/questions/11229831/regular-expression-to-remove-html-tags-from-a-string" - } + { + "name": "Markdown links", + "pattern": "\\((.*)\\)", + "description": "" + }, + { + "name": "Markdown code blocks", + "pattern": "/^(\\s*`{3,}).*[\\s\\S]*?^\\1/gmx", + "description": "Taken from the cSpell example at https://cspell.org/configuration/patterns/#verbose-regular-expressions" + }, + { + "name": "Inline code blocks", + "pattern": "\\`([^\\`\\r\\n]+?)\\`", + "description": "https://stackoverflow.com/questions/41274241/how-to-capture-inline-markdown-code-but-not-a-markdown-code-fence-with-regex" + }, + { + "name": "Link contents", + "pattern": "\\", + "description": "" + }, + { + "name": "Snippet references", + "pattern": "-- snippet:(.*)", + "description": "" + }, + { + "name": "Snippet references 2", + "pattern": "\\<\\[sample:(.*)", + "description": "another kind of snippet reference" + }, + { + "name": "Multi-line code blocks", + "pattern": "/^\\s*```[\\s\\S]*?^\\s*```/gm" + }, + { + "name": "HTML Tags", + "pattern": "<[^>]*>", + "description": "Reference: https://stackoverflow.com/questions/11229831/regular-expression-to-remove-html-tags-from-a-string" + } ], "ignoreRegExpList": [ - "Markdown links", - "Markdown code blocks", - "Inline code blocks", - "Link contents", - "Snippet references", - "Snippet references 2", - "Multi-line code blocks", - "HTML Tags" + "Markdown links", + "Markdown code blocks", + "Inline code blocks", + "Link contents", + "Snippet references", + "Snippet references 2", + "Multi-line code blocks", + "HTML Tags" ], "ignorePaths": [] - } \ No newline at end of file +} From 6c992f9e3e457144e413bf2ffd81d7bccad43fcb Mon Sep 17 00:00:00 2001 From: Sean Killeen Date: Tue, 18 Oct 2022 23:30:29 -0400 Subject: [PATCH 024/124] Add markdown image exclusion --- cSpell.json | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/cSpell.json b/cSpell.json index 980bfd2750..e3bd59fcfc 100644 --- a/cSpell.json +++ b/cSpell.json @@ -2,7 +2,10 @@ "version": "0.2", "language": "en", "words": [ - "Blazor" + "Blazor", + "Sweetalert", + "Toastr", + "Volo" ], "ignoreWords": [], "patterns": [ @@ -44,6 +47,10 @@ "name": "HTML Tags", "pattern": "<[^>]*>", "description": "Reference: https://stackoverflow.com/questions/11229831/regular-expression-to-remove-html-tags-from-a-string" + }, + { + "name": "Markdown Image", + "pattern": "!\\[(.*)\\]\\((.*)\\)" } ], "ignoreRegExpList": [ @@ -54,7 +61,8 @@ "Snippet references", "Snippet references 2", "Multi-line code blocks", - "HTML Tags" + "HTML Tags", + "Markdown Image" ], "ignorePaths": [] } From 19713bacb316cc4af7ed3e23d3c201139ca8b86f Mon Sep 17 00:00:00 2001 From: Sean Killeen Date: Tue, 18 Oct 2022 23:33:58 -0400 Subject: [PATCH 025/124] add known words --- cSpell.json | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/cSpell.json b/cSpell.json index e3bd59fcfc..6453442b7a 100644 --- a/cSpell.json +++ b/cSpell.json @@ -2,9 +2,19 @@ "version": "0.2", "language": "en", "words": [ + "aspnetcore", "Blazor", + "Datatable", + "datepicker", + "dismissable", + "hoverable", + "Luxon", + "Minifier", + "scrollbars", "Sweetalert", + "Templating", "Toastr", + "toolset", "Volo" ], "ignoreWords": [], From 7abc37c0e39710457d655e70af3d48b5f54b3e06 Mon Sep 17 00:00:00 2001 From: Sean Killeen Date: Tue, 18 Oct 2022 23:37:01 -0400 Subject: [PATCH 026/124] add known words --- cSpell.json | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/cSpell.json b/cSpell.json index 6453442b7a..97eff4ac55 100644 --- a/cSpell.json +++ b/cSpell.json @@ -4,18 +4,27 @@ "words": [ "aspnetcore", "Blazor", + "CQRS", + "Dapr", "Datatable", "datepicker", "dismissable", "hoverable", + "Iddict", + "Keysize", + "Linq", "Luxon", "Minifier", + "PKCE", "scrollbars", + "Shoudly", "Sweetalert", + "Telerik", "Templating", "Toastr", "toolset", - "Volo" + "Volo", + "Xunit" ], "ignoreWords": [], "patterns": [ From 7bcc40b969a320405e5d0d89704bef57cbaf9722 Mon Sep 17 00:00:00 2001 From: Sean Killeen Date: Tue, 18 Oct 2022 23:43:53 -0400 Subject: [PATCH 027/124] back-ticks --- docs/en/UI/AspNetCore/Client-Side-Package-Management.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/en/UI/AspNetCore/Client-Side-Package-Management.md b/docs/en/UI/AspNetCore/Client-Side-Package-Management.md index e9e4e04de5..dc242e163d 100644 --- a/docs/en/UI/AspNetCore/Client-Side-Package-Management.md +++ b/docs/en/UI/AspNetCore/Client-Side-Package-Management.md @@ -18,7 +18,7 @@ To solve the versioning problem, we created a **standard set of packages** those The benefit of a **standard package** is: * It depends on a **standard version** of a package. Depending on this package is **safe** because all modules depend on the same version. -* It contains the mappings copy library resources (js, css, img... files) from the **node_modules** folder to **wwwroot/libs** folder. See the *Mapping The Library Resources* section for more. +* It contains the mappings copy library resources (js, css, img... files) from the `node_modules` folder to `wwwroot/libs` folder. See the *Mapping The Library Resources* section for more. Depending on a standard package is easy. Just add it to your **package.json** file like you normally do. Example: @@ -57,7 +57,7 @@ See current standard packages for examples. ### Mapping The Library Resources -Using NPM packages and NPM/Yarn tool is the de facto standard for client side libraries. NPM/Yarn tool creates a **node_modules** folder in the root folder of your web project. +Using NPM packages and NPM/Yarn tool is the de facto standard for client side libraries. NPM/Yarn tool creates a **node_modules** folder in the root folder of your web project. Next challenge is copying needed resources (js, css, img... files) from the `node_modules` into a folder inside the **wwwroot** folder to make it accessible to the clients/browsers. @@ -108,7 +108,7 @@ Once you properly configure the `abp.resourcemapping.js` file, you can run the f abp install-libs ```` -When you run this command, all packages will copy their own resources into the **wwwroot/libs** folder. Running `abp install-libs` is only necessary if you make a change in your dependencies in the **package.json** file. +When you run this command, all packages will copy their own resources into the `wwwroot/libs` folder. Running `abp install-libs` is only necessary if you make a change in your dependencies in the **package.json** file. #### See Also From 9f1a1691db2e9ddf0dfc0d6e080e038a7eaacf39 Mon Sep 17 00:00:00 2001 From: Sean Killeen Date: Tue, 18 Oct 2022 23:43:56 -0400 Subject: [PATCH 028/124] add words --- cSpell.json | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/cSpell.json b/cSpell.json index 97eff4ac55..db0fcbfbfc 100644 --- a/cSpell.json +++ b/cSpell.json @@ -2,25 +2,35 @@ "version": "0.2", "language": "en", "words": [ + "ABP's", "aspnetcore", "Blazor", "CQRS", + "crossfade", "Dapr", "Datatable", "datepicker", "dismissable", + "Formik", "hoverable", "Iddict", "Keysize", "Linq", "Luxon", + "malihu", "Minifier", + "NSWAG", + "oidc", "PKCE", + "preconfigured", "scrollbars", "Shoudly", + "Shouldly", "Sweetalert", + "Syncfusion", "Telerik", "Templating", + "Timeago", "Toastr", "toolset", "Volo", From a4fa5fc0ceaf797519f4010378c6224f5c5a6b60 Mon Sep 17 00:00:00 2001 From: Sean Killeen Date: Tue, 18 Oct 2022 23:47:52 -0400 Subject: [PATCH 029/124] add words --- cSpell.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cSpell.json b/cSpell.json index db0fcbfbfc..4b819d7828 100644 --- a/cSpell.json +++ b/cSpell.json @@ -3,6 +3,7 @@ "language": "en", "words": [ "ABP's", + "abpframework", "aspnetcore", "Blazor", "CQRS", @@ -24,6 +25,7 @@ "PKCE", "preconfigured", "scrollbars", + "Serilog", "Shoudly", "Shouldly", "Sweetalert", From 6d187c6f9b8b6258a60741c8f0e08f140f183dcb Mon Sep 17 00:00:00 2001 From: Sean Killeen Date: Tue, 18 Oct 2022 23:53:53 -0400 Subject: [PATCH 030/124] spacing --- .../OpenIddict-Step-by-Step.md | 85 ++++++++++--------- 1 file changed, 45 insertions(+), 40 deletions(-) diff --git a/docs/en/Migration-Guides/OpenIddict-Step-by-Step.md b/docs/en/Migration-Guides/OpenIddict-Step-by-Step.md index ba6b264758..b6ad9172da 100644 --- a/docs/en/Migration-Guides/OpenIddict-Step-by-Step.md +++ b/docs/en/Migration-Guides/OpenIddict-Step-by-Step.md @@ -19,13 +19,16 @@ Use the `abp update` command to update your existing application. See [Upgrading ### Domain.Shared Layer - In **MyApplication.Domain.Shared.csproj** replace **project reference**: - ```csharp - - ``` + +```csharp + +``` + with - ```csharp - - ``` + +```csharp + +``` - In **MyApplicationDomainSharedModule.cs** replace usings and **module dependencies:** @@ -34,7 +37,9 @@ Use the `abp update` command to update your existing application. See [Upgrading ... typeof(AbpIdentityServerDomainSharedModule) ``` + with + ```csharp using Volo.Abp.OpenIddict; ... @@ -58,23 +63,23 @@ Use the `abp update` command to update your existing application. See [Upgrading - In **MyApplicationDomainModule.cs** replace usings and **module dependencies**: - ```csharp - using Volo.Abp.IdentityServer; - using Volo.Abp.PermissionManagement.IdentityServer; - ... - typeof(AbpIdentityServerDomainModule), - typeof(AbpPermissionManagementDomainIdentityServerModule), - ``` +```csharp +using Volo.Abp.IdentityServer; +using Volo.Abp.PermissionManagement.IdentityServer; +... +typeof(AbpIdentityServerDomainModule), +typeof(AbpPermissionManagementDomainIdentityServerModule), +``` with - ```csharp - using Volo.Abp.OpenIddict; - using Volo.Abp.PermissionManagement.OpenIddict; - ... - typeof(AbpOpenIddictDomainModule), - typeof(AbpPermissionManagementDomainOpenIddictModule), - ``` +```csharp +using Volo.Abp.OpenIddict; +using Volo.Abp.PermissionManagement.OpenIddict; +... +typeof(AbpOpenIddictDomainModule), +typeof(AbpPermissionManagementDomainOpenIddictModule), +``` #### OpenIddictDataSeedContributor @@ -101,19 +106,19 @@ If you are using MongoDB, skip this step and check the *MongoDB* layer section. - In **MyApplicationEntityFrameworkCoreModule.cs** replace usings and **module dependencies**: - ```csharp - using Volo.Abp.IdentityServer.EntityFrameworkCore; - ... - typeof(AbpIdentityServerEntityFrameworkCoreModule), - ``` +```csharp +using Volo.Abp.IdentityServer.EntityFrameworkCore; +... +typeof(AbpIdentityServerEntityFrameworkCoreModule), +``` with - ```csharp - using Volo.Abp.OpenIddict.EntityFrameworkCore; - ... - typeof(AbpOpenIddictEntityFrameworkCoreModule), - ``` +```csharp +using Volo.Abp.OpenIddict.EntityFrameworkCore; +... +typeof(AbpOpenIddictEntityFrameworkCoreModule), +``` - In **MyApplicationDbContext.cs** replace usings and **fluent api configurations**: @@ -165,19 +170,19 @@ If you are using EntityFrameworkCore, skip this step and check the *EntityFramew - In **MyApplicationMongoDbModule.cs** replace usings and **module dependencies**: - ```csharp - using Volo.Abp.IdentityServer.MongoDB; - ... - typeof(AbpIdentityServerMongoDbModule), - ``` +```csharp +using Volo.Abp.IdentityServer.MongoDB; +... +typeof(AbpIdentityServerMongoDbModule), +``` with - ```csharp - using Volo.Abp.OpenIddict.MongoDB; - ... - typeof(AbpOpenIddictMongoDbModule), - ``` +```csharp +using Volo.Abp.OpenIddict.MongoDB; +... +typeof(AbpOpenIddictMongoDbModule), +``` ### DbMigrator Project From 33af7b9e85ad45f6457482539eb424a0ae4f851f Mon Sep 17 00:00:00 2001 From: Sean Killeen Date: Tue, 18 Oct 2022 23:53:57 -0400 Subject: [PATCH 031/124] add words --- cSpell.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cSpell.json b/cSpell.json index 4b819d7828..ac8dd3f916 100644 --- a/cSpell.json +++ b/cSpell.json @@ -5,6 +5,7 @@ "ABP's", "abpframework", "aspnetcore", + "Autofac", "Blazor", "CQRS", "crossfade", @@ -20,10 +21,12 @@ "Luxon", "malihu", "Minifier", + "Newtonsoft", "NSWAG", "oidc", "PKCE", "preconfigured", + "proxying", "scrollbars", "Serilog", "Shoudly", From cd725bd79c5716c34112ca9b53daf19b2e9a1e5f Mon Sep 17 00:00:00 2001 From: Sean Killeen Date: Tue, 18 Oct 2022 23:54:40 -0400 Subject: [PATCH 032/124] add words --- cSpell.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cSpell.json b/cSpell.json index ac8dd3f916..1025fd560e 100644 --- a/cSpell.json +++ b/cSpell.json @@ -4,6 +4,7 @@ "words": [ "ABP's", "abpframework", + "aspnet", "aspnetcore", "Autofac", "Blazor", @@ -13,6 +14,7 @@ "Datatable", "datepicker", "dismissable", + "dockerized", "Formik", "hoverable", "Iddict", From 49940b4b306221246a8220ff460e35856968f14c Mon Sep 17 00:00:00 2001 From: Sean Killeen Date: Tue, 18 Oct 2022 23:57:47 -0400 Subject: [PATCH 033/124] Fix: "Width" --- docs/en/UI/Angular/Chart-Component.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/UI/Angular/Chart-Component.md b/docs/en/UI/Angular/Chart-Component.md index a1cea80b52..ec78fa56a1 100644 --- a/docs/en/UI/Angular/Chart-Component.md +++ b/docs/en/UI/Angular/Chart-Component.md @@ -232,7 +232,7 @@ See the [`chart.js` samples](https://www.chartjs.org/docs/latest/samples) for mo | `[data]` | Chart data to display | `any` | null | | `[options]` | Chart options to customize | `any` | null | | `[plugins]` | Chart plugins to customize behaviour | `any` | null | -| `[width]` | Witdh of the chart | `string` | null | +| `[width]` | Width of the chart | `string` | null | | `[height]` | Height of the chart | `string` | null | | `[responsive]` | Whether the chart is responsive | `boolean` | true | | `(dataSelect)` | A callback that executes when an element on the chart is clicked | `EventEmitter` | - | From 56afa4176a890d9fd4abfb18799b70ddb82f1f02 Mon Sep 17 00:00:00 2001 From: Sean Killeen Date: Tue, 18 Oct 2022 23:58:15 -0400 Subject: [PATCH 034/124] Fix: "Signal" --- docs/en/SignalR-Integration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/SignalR-Integration.md b/docs/en/SignalR-Integration.md index 35f109b8e6..d532067911 100644 --- a/docs/en/SignalR-Integration.md +++ b/docs/en/SignalR-Integration.md @@ -235,4 +235,4 @@ Refer to the Microsoft's documentation to [host and scale](https://docs.microsof ## See Also - [Microsoft SignalR documentation](https://docs.microsoft.com/en-us/aspnet/core/signalr/introduction) -- [Real-Time Messaging In A Distributed Architecture Using ABP, SingalR & RabbitMQ](https://volosoft.com/blog/RealTime-Messaging-Distributed-Architecture-Abp-SingalR-RabbitMQ) +- [Real-Time Messaging In A Distributed Architecture Using ABP, SignalR & RabbitMQ](https://volosoft.com/blog/RealTime-Messaging-Distributed-Architecture-Abp-SingalR-RabbitMQ) From 2ffda972e5998509d2cec995a9dc3748dcd87e52 Mon Sep 17 00:00:00 2001 From: Sean Killeen Date: Tue, 18 Oct 2022 23:58:47 -0400 Subject: [PATCH 035/124] fix: OpenIddict --- docs/en/Migration-Guides/OpenIddict-Step-by-Step.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/Migration-Guides/OpenIddict-Step-by-Step.md b/docs/en/Migration-Guides/OpenIddict-Step-by-Step.md index b6ad9172da..f3589c5111 100644 --- a/docs/en/Migration-Guides/OpenIddict-Step-by-Step.md +++ b/docs/en/Migration-Guides/OpenIddict-Step-by-Step.md @@ -256,7 +256,7 @@ for creating the host builder. ## Source code of samples and module -* [Open source tiered & separate auth server application migrate Identity Server to OpenIddct](https://github.com/abpframework/abp-samples/tree/master/Ids2OpenId) +* [Open source tiered & separate auth server application migrate Identity Server to OpenIddict](https://github.com/abpframework/abp-samples/tree/master/Ids2OpenId) * [OpenIddict module document](https://docs.abp.io/en/abp/6.0/Modules/OpenIddict) * [OpenIddict module source code](https://github.com/abpframework/abp/tree/rel-6.0/modules/openiddict) From 8f0560ade487ac17a511fadc74fecaee837465a2 Mon Sep 17 00:00:00 2001 From: Sean Killeen Date: Tue, 18 Oct 2022 23:59:15 -0400 Subject: [PATCH 036/124] fix: "least" --- docs/en/Modules/Cms-Kit/Index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/Modules/Cms-Kit/Index.md b/docs/en/Modules/Cms-Kit/Index.md index b8cbe89d20..5b7f3b5366 100644 --- a/docs/en/Modules/Cms-Kit/Index.md +++ b/docs/en/Modules/Cms-Kit/Index.md @@ -22,7 +22,7 @@ All features are individually usable. If you disable a feature, it completely di ## Pre Requirements - This module depends on [BlobStoring](../../Blob-Storing.md) module for keeping media content. -> Make sure `BlobStoring` module is installed and at leats one provider is configured properly. For more information, check the [documentation](../../Blob-Storing.md). +> Make sure `BlobStoring` module is installed and at least one provider is configured properly. For more information, check the [documentation](../../Blob-Storing.md). - CMS Kit uses [distributed cache](../../Caching.md) for responding faster. > Using a distributed cache, such as [Redis](../../Redis-Cache.md), is highly recommended for data consistency in distributed/clustered deployments. From 474b3f7e6851ec325466873f4c35e36da404c7aa Mon Sep 17 00:00:00 2001 From: Sean Killeen Date: Wed, 19 Oct 2022 00:01:23 -0400 Subject: [PATCH 037/124] fix: "OpenIddict" --- docs/en/Migration-Guides/IdentityServer_To_OpenIddict.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/Migration-Guides/IdentityServer_To_OpenIddict.md b/docs/en/Migration-Guides/IdentityServer_To_OpenIddict.md index a4baa79d9f..d60493be7a 100644 --- a/docs/en/Migration-Guides/IdentityServer_To_OpenIddict.md +++ b/docs/en/Migration-Guides/IdentityServer_To_OpenIddict.md @@ -72,7 +72,7 @@ private void ConfigureAuthentication(ServiceConfigurationContext context) ## Source code of samples and module -* [Open source tiered & separate auth server application migrate Identity Server to OpenIddct](https://github.com/abpframework/abp-samples/tree/master/Ids2OpenId) -* [Commercial tiered & separate auth server application migrate Identity Server to OpenIddct](https://abp.io/Account/Login?returnUrl=/api/download/samples/Ids2OpenId) +* [Open source tiered & separate auth server application migrate Identity Server to OpenIddict](https://github.com/abpframework/abp-samples/tree/master/Ids2OpenId) +* [Commercial tiered & separate auth server application migrate Identity Server to OpenIddict](https://abp.io/Account/Login?returnUrl=/api/download/samples/Ids2OpenId) * [OpenIddict module document](https://docs.abp.io/en/abp/6.0/Modules/OpenIddict) * [OpenIddict module source code](https://github.com/abpframework/abp/tree/rel-6.0/modules/openiddict) From 933154984104c8d8babc095a44c26a951e2f67c0 Mon Sep 17 00:00:00 2001 From: Sean Killeen Date: Wed, 19 Oct 2022 00:01:48 -0400 Subject: [PATCH 038/124] fix: "separate" --- docs/en/Dependency-Injection.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/Dependency-Injection.md b/docs/en/Dependency-Injection.md index a0ad342c4c..bfce8a71bf 100644 --- a/docs/en/Dependency-Injection.md +++ b/docs/en/Dependency-Injection.md @@ -6,7 +6,7 @@ ABP's Dependency Injection system is developed based on Microsoft's [dependency ## Modularity -Since ABP is a modular framework, every module defines it's own services and registers via dependency injection in it's own seperate [module class](Module-Development-Basics.md). Example: +Since ABP is a modular framework, every module defines it's own services and registers via dependency injection in it's own separate [module class](Module-Development-Basics.md). Example: ````C# public class BlogModule : AbpModule From 87a4e7c384b35e258d254c2aaf52778436d64b94 Mon Sep 17 00:00:00 2001 From: Sean Killeen Date: Wed, 19 Oct 2022 00:02:08 -0400 Subject: [PATCH 039/124] fix: "article" --- .../How-to-Contribute-abp.io-as-a-frontend-developer.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/Contribution/How-to-Contribute-abp.io-as-a-frontend-developer.md b/docs/en/Contribution/How-to-Contribute-abp.io-as-a-frontend-developer.md index 637a87624b..a1cfa22df8 100644 --- a/docs/en/Contribution/How-to-Contribute-abp.io-as-a-frontend-developer.md +++ b/docs/en/Contribution/How-to-Contribute-abp.io-as-a-frontend-developer.md @@ -11,7 +11,7 @@ - Abp CLI https://docs.abp.io/en/abp/latest/cli - A code editor -Note: This arcticle prepare Windows OS. You may change the path type of your OS. an Example +Note: This article prepare Windows OS. You may change the path type of your OS. an Example Windows: `templates\app\aspnet-core\src\MyCompanyName.MyProjectName.DbMigrator\appsettings.json` From 2d395ab2e9101669831f0e4a08f4ee13f01df762 Mon Sep 17 00:00:00 2001 From: Sean Killeen Date: Wed, 19 Oct 2022 00:02:31 -0400 Subject: [PATCH 040/124] fix: "archive" --- .../README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/Community-Articles/2022-02-22-Integrating-MAUI-Client-via-using-OpenID-Connect/README.md b/docs/en/Community-Articles/2022-02-22-Integrating-MAUI-Client-via-using-OpenID-Connect/README.md index 0d86c98a1d..094f8a8d9d 100644 --- a/docs/en/Community-Articles/2022-02-22-Integrating-MAUI-Client-via-using-OpenID-Connect/README.md +++ b/docs/en/Community-Articles/2022-02-22-Integrating-MAUI-Client-via-using-OpenID-Connect/README.md @@ -597,5 +597,5 @@ In this step we have to store access token & refresh token for future requests. The purpose of this arcitle is connecting to ABP backend with access token and it's working properly. -I'm planning to integrate HttpApi.Client library of backend project instead of making requests manually as a second part of this article. I'll get inspired by [hikalkan/maui-abp-playing](https://github.com/hikalkan/maui-abp-playing) repo to achive that. +I'm planning to integrate HttpApi.Client library of backend project instead of making requests manually as a second part of this article. I'll get inspired by [hikalkan/maui-abp-playing](https://github.com/hikalkan/maui-abp-playing) repo to archive that. From bbf4f45af390129ebb845eb2d12e3278c2d37955 Mon Sep 17 00:00:00 2001 From: Sean Killeen Date: Wed, 19 Oct 2022 00:03:03 -0400 Subject: [PATCH 041/124] fix: "Storage" --- .../POST.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/Community-Articles/2020-07-21-File-Upload-Download-With-BLOB-Storage-System-in-ASPNET-Core-ABP-Framework/POST.md b/docs/en/Community-Articles/2020-07-21-File-Upload-Download-With-BLOB-Storage-System-in-ASPNET-Core-ABP-Framework/POST.md index 560e15e288..c617c03a45 100644 --- a/docs/en/Community-Articles/2020-07-21-File-Upload-Download-With-BLOB-Storage-System-in-ASPNET-Core-ABP-Framework/POST.md +++ b/docs/en/Community-Articles/2020-07-21-File-Upload-Download-With-BLOB-Storage-System-in-ASPNET-Core-ABP-Framework/POST.md @@ -48,9 +48,9 @@ Open a command prompt (terminal) in the folder containing your solution (.sln) f This action will add the module depencies and also module migration. After this action, run `FileActionsDemo.DbMigrator` to update the database. -### Setting up Blob Storaging +### Setting up Blob Storage -BLOB Strorage system works with `Containers`. Before the using blob storage, we need to create our blob container. +BLOB Storage system works with `Containers`. Before the using blob storage, we need to create our blob container. Create a class that name `MyFileContainer` at the `FileActionsDemo.Domain` project. From d819b956f4a015b50ace113811d3a2118978b591 Mon Sep 17 00:00:00 2001 From: Sean Killeen Date: Wed, 19 Oct 2022 00:03:26 -0400 Subject: [PATCH 042/124] fix: "dependencies" --- .../POST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/Community-Articles/2020-07-21-File-Upload-Download-With-BLOB-Storage-System-in-ASPNET-Core-ABP-Framework/POST.md b/docs/en/Community-Articles/2020-07-21-File-Upload-Download-With-BLOB-Storage-System-in-ASPNET-Core-ABP-Framework/POST.md index c617c03a45..a6fb03d6c4 100644 --- a/docs/en/Community-Articles/2020-07-21-File-Upload-Download-With-BLOB-Storage-System-in-ASPNET-Core-ABP-Framework/POST.md +++ b/docs/en/Community-Articles/2020-07-21-File-Upload-Download-With-BLOB-Storage-System-in-ASPNET-Core-ABP-Framework/POST.md @@ -46,7 +46,7 @@ Open a command prompt (terminal) in the folder containing your solution (.sln) f `abp add-module Volo.Abp.BlobStoring.Database` -This action will add the module depencies and also module migration. After this action, run `FileActionsDemo.DbMigrator` to update the database. +This action will add the module dependencies and also module migration. After this action, run `FileActionsDemo.DbMigrator` to update the database. ### Setting up Blob Storage From fcbce3283f5fb8ca6fe06507fa6a9a5e4b4c0c9b Mon Sep 17 00:00:00 2001 From: Sean Killeen Date: Wed, 19 Oct 2022 00:03:45 -0400 Subject: [PATCH 043/124] fix: "SignalR --- .../POST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/Community-Articles/2020-05-29-Real-Time-Messaging-In-A-Distributed-Architecture-Using-Abp-Framework-SingalR-RabbitMQ/POST.md b/docs/en/Community-Articles/2020-05-29-Real-Time-Messaging-In-A-Distributed-Architecture-Using-Abp-Framework-SingalR-RabbitMQ/POST.md index eea0eaae46..0d09112681 100644 --- a/docs/en/Community-Articles/2020-05-29-Real-Time-Messaging-In-A-Distributed-Architecture-Using-Abp-Framework-SingalR-RabbitMQ/POST.md +++ b/docs/en/Community-Articles/2020-05-29-Real-Time-Messaging-In-A-Distributed-Architecture-Using-Abp-Framework-SingalR-RabbitMQ/POST.md @@ -1,4 +1,4 @@ -# Real Time Messaging In A Distributed Architecture Using Abp Framework, SingalR & RabbitMQ +# Real Time Messaging In A Distributed Architecture Using Abp Framework, SignalR & RabbitMQ In this article, we will build a basic real time messaging application in a distributed architecture. We will use [Abp Framework](https://abp.io) for infrastructure and tiered startup template, [SignalR](https://dotnet.microsoft.com/apps/aspnet/signalr) for real time server-client communication and [RabbitMQ](https://www.rabbitmq.com/) as the distributed event bus. From cec0470fd60f27534e583ff6a222e9fc0415d0ae Mon Sep 17 00:00:00 2001 From: Sean Killeen Date: Wed, 19 Oct 2022 00:04:55 -0400 Subject: [PATCH 044/124] fix: "configured" --- .../POST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/Community-Articles/2020-04-27-Use-Azure-Active-Directory-Authentication-for-MVC-Razor-Page-Applications/POST.md b/docs/en/Community-Articles/2020-04-27-Use-Azure-Active-Directory-Authentication-for-MVC-Razor-Page-Applications/POST.md index b2c307bcb3..f63741f49a 100644 --- a/docs/en/Community-Articles/2020-04-27-Use-Azure-Active-Directory-Authentication-for-MVC-Razor-Page-Applications/POST.md +++ b/docs/en/Community-Articles/2020-04-27-Use-Azure-Active-Directory-Authentication-for-MVC-Razor-Page-Applications/POST.md @@ -12,7 +12,7 @@ Two different **alternative approaches** for AzureAD integration will be demonst > There is **no difference** in functionality between these approaches. AddAzureAD is an abstracted way of OpenIdConnection ([source](https://github.com/dotnet/aspnetcore/blob/c56aa320c32ee5429d60647782c91d53ac765865/src/Azure/AzureAD/Authentication.AzureAD.UI/src/AzureADAuthenticationBuilderExtensions.cs#L122)) with predefined cookie settings. > -> However there are key differences in integration to ABP applications because of default configurated signin schemes which will be explained below. +> However there are key differences in integration to ABP applications because of default configured signin schemes which will be explained below. ## 1. AddOpenIdConnect From 0176d8f502bde3aa9d0a2799b1e5ec4d815bc3d8 Mon Sep 17 00:00:00 2001 From: Sean Killeen Date: Wed, 19 Oct 2022 00:05:33 -0400 Subject: [PATCH 045/124] add word --- cSpell.json | 1 + 1 file changed, 1 insertion(+) diff --git a/cSpell.json b/cSpell.json index 1025fd560e..1a1534bef1 100644 --- a/cSpell.json +++ b/cSpell.json @@ -26,6 +26,7 @@ "Newtonsoft", "NSWAG", "oidc", + "Parameterless", "PKCE", "preconfigured", "proxying", From 20fc1eae1ae92927da1a1085ca88cde7d6efddc8 Mon Sep 17 00:00:00 2001 From: Sean Killeen Date: Wed, 19 Oct 2022 00:08:16 -0400 Subject: [PATCH 046/124] fix: "formatting" --- docs/en/Migration-Guides/Abp-5_2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/Migration-Guides/Abp-5_2.md b/docs/en/Migration-Guides/Abp-5_2.md index d0cbf80aad..aeb79e22a6 100644 --- a/docs/en/Migration-Guides/Abp-5_2.md +++ b/docs/en/Migration-Guides/Abp-5_2.md @@ -15,7 +15,7 @@ We've upgraded to Blazorise 1.0 stable version. So there is some breaking change Also You can review that pull request [#11649 - Blazorise 1.0 Migration](https://github.com/abpframework/abp/pull/11649) -- `NumericEdit` is now made around the native `input type="number"` so a lot of its formating features are moved to the new `NumericPicker` component. Replace NumericEdit with NumericPicker. +- `NumericEdit` is now made around the native `input type="number"` so a lot of its formatting features are moved to the new `NumericPicker` component. Replace NumericEdit with NumericPicker. - Rename `DecimalsSeparator` to `DecimalSeparator` on the `DataGridColumn` and `NumericPicker`. - Rename `MaxMessageSize` to `MaxChunkSize`. - Remove `Fullscreen` parameter on `` and replace it with `Size="ModalSize.Fullscreen"` parameter. From af9fecbfdbecdb1353f6d1dcf1fc771595e08d06 Mon Sep 17 00:00:00 2001 From: Sean Killeen Date: Wed, 19 Oct 2022 00:08:56 -0400 Subject: [PATCH 047/124] fix: class --- docs/en/Distributed-Event-Bus-Rebus-Integration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/Distributed-Event-Bus-Rebus-Integration.md b/docs/en/Distributed-Event-Bus-Rebus-Integration.md index 7499c1d837..39fb35ede9 100644 --- a/docs/en/Distributed-Event-Bus-Rebus-Integration.md +++ b/docs/en/Distributed-Event-Bus-Rebus-Integration.md @@ -18,7 +18,7 @@ You can configure using the standard [configuration system](Configuration.md), l ### The Options Classes -`AbpRebusEventBusOptions` classe can be used to configure the event bus options for the Rebus. +`AbpRebusEventBusOptions` class can be used to configure the event bus options for the Rebus. You can configure this options inside the `PreConfigureServices` of your [module](Module-Development-Basics.md). From 0031fd4f4031b81f98232ca2cae5e9e9dccfa6f8 Mon Sep 17 00:00:00 2001 From: Sean Killeen Date: Wed, 19 Oct 2022 00:12:11 -0400 Subject: [PATCH 048/124] dict adds --- cSpell.json | 1 + 1 file changed, 1 insertion(+) diff --git a/cSpell.json b/cSpell.json index 1a1534bef1..87b1ca7881 100644 --- a/cSpell.json +++ b/cSpell.json @@ -4,6 +4,7 @@ "words": [ "ABP's", "abpframework", + "Antiforgery", "aspnet", "aspnetcore", "Autofac", From 2688095f44da8f0051575d2a8b54f026bc7d57e1 Mon Sep 17 00:00:00 2001 From: Sean Killeen Date: Wed, 19 Oct 2022 00:12:20 -0400 Subject: [PATCH 049/124] fix: "Reusable" --- docs/en/Specifications.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/Specifications.md b/docs/en/Specifications.md index a9aeb2b050..2ef9c4496e 100644 --- a/docs/en/Specifications.md +++ b/docs/en/Specifications.md @@ -246,7 +246,7 @@ So, what's the point of a specification? Why and when should we consider to use Some benefits of using specifications: -- **Reusabe**: Imagine that you need the Premium Customer filter in many places in your code base. If you go with expressions and do not create a specification, what happens if you later change the "Premium Customer" definition? Say you want to change the minimum balance from $100,000 to $250,000 and add another condition to be a customer older than 3 years. If you'd used a specification, you just change a single class. If you repeated (copy/pasted) the same expression everywhere, you need to change all of them. +- **Reusable**: Imagine that you need the Premium Customer filter in many places in your code base. If you go with expressions and do not create a specification, what happens if you later change the "Premium Customer" definition? Say you want to change the minimum balance from $100,000 to $250,000 and add another condition to be a customer older than 3 years. If you'd used a specification, you just change a single class. If you repeated (copy/pasted) the same expression everywhere, you need to change all of them. - **Composable**: You can combine multiple specifications to create new specifications. This is another type of reusability. - **Named**: `PremiumCustomerSpecification` better explains the intent rather than a complex expression. So, if you have an expression that is meaningful in your business, consider using specifications. - **Testable**: A specification is a separately (and easily) testable object. From e0e415a8cfa9c7c18e960c0f4e92ca6d84bf5ffe Mon Sep 17 00:00:00 2001 From: Sean Killeen Date: Wed, 19 Oct 2022 00:12:47 -0400 Subject: [PATCH 050/124] add word --- cSpell.json | 1 + 1 file changed, 1 insertion(+) diff --git a/cSpell.json b/cSpell.json index 87b1ca7881..921d351f29 100644 --- a/cSpell.json +++ b/cSpell.json @@ -9,6 +9,7 @@ "aspnetcore", "Autofac", "Blazor", + "Blazorise", "CQRS", "crossfade", "Dapr", From 7c1934fe32ecae89ec92251963a2e9b2ba981dd6 Mon Sep 17 00:00:00 2001 From: Sean Killeen Date: Wed, 19 Oct 2022 00:14:17 -0400 Subject: [PATCH 051/124] fix: "contributor" --- docs/en/UI/Angular/Dynamic-Form-Extensions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/UI/Angular/Dynamic-Form-Extensions.md b/docs/en/UI/Angular/Dynamic-Form-Extensions.md index 1764b0cad7..f576dcafdc 100644 --- a/docs/en/UI/Angular/Dynamic-Form-Extensions.md +++ b/docs/en/UI/Angular/Dynamic-Form-Extensions.md @@ -7,7 +7,7 @@ Form prop extension system allows you to add a new field to the create and/or ed Form Prop Extension Example: 'Date of Birth' Field -You can validate the field, perform visibility checks, and do more. You will also have access to the current entity when creating a contibutor for an edit form. +You can validate the field, perform visibility checks, and do more. You will also have access to the current entity when creating a contributor for an edit form. ## How to Set Up From 1627b88a6f943be77890de4f34561cacfdc39d08 Mon Sep 17 00:00:00 2001 From: Sean Killeen Date: Wed, 19 Oct 2022 00:14:32 -0400 Subject: [PATCH 052/124] fix: "parameters" --- docs/en/UI/Angular/Loading-Strategy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/UI/Angular/Loading-Strategy.md b/docs/en/UI/Angular/Loading-Strategy.md index 5322d13eda..a222233088 100644 --- a/docs/en/UI/Angular/Loading-Strategy.md +++ b/docs/en/UI/Angular/Loading-Strategy.md @@ -102,7 +102,7 @@ Sets given paremeters and `crossorigin="anonymous"` as attributes of created `` element and places it at the **beginning** of `` tag in the document. +Sets given parameters and `crossorigin="anonymous"` as attributes of created `