Remove `HybridJson`.

pull/13357/head
maliming 3 years ago
parent e2748ce82a
commit ff2ecc004f

@ -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

@ -19,6 +19,7 @@
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.AspNetCore.Mvc\Volo.Abp.AspNetCore.Mvc.csproj" />
<ProjectReference Include="..\Volo.Abp.Json.Newtonsoft\Volo.Abp.Json.Newtonsoft.csproj" />
</ItemGroup>
<ItemGroup>

@ -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<ObjectPoolProvider, DefaultObjectPoolProvider>();
Configure<MvcOptions>(mvcOptions =>
{
mvcOptions.InputFormatters.RemoveType<NewtonsoftJsonInputFormatter>();
mvcOptions.OutputFormatters.RemoveType<NewtonsoftJsonOutputFormatter>();
});
Configure<AbpHybridJsonFormatterOptions>(formatterOptions =>
{
formatterOptions.TextInputFormatters.Add<AbpNewtonsoftJsonFormatter>();
formatterOptions.TextOutputFormatters.Add<AbpNewtonsoftJsonFormatter>();
});
context.Services.AddMvcCore().AddNewtonsoftJson();
context.Services.AddOptions<MvcNewtonsoftJsonOptions>()
.Configure<IServiceProvider>((options, serviceProvider) =>
.Configure<AbpCamelCasePropertyNamesContractResolver>((options, contractResolver) =>
{
options.SerializerSettings.ContractResolver = serviceProvider.GetRequiredService<AbpCamelCasePropertyNamesContractResolver>();
var converters = serviceProvider.GetRequiredService<IOptions<AbpNewtonsoftJsonSerializerOptions>>().Value
.Converters.Select(converterType => serviceProvider.GetRequiredService(converterType).As<JsonConverter>())
.ToList();
options.SerializerSettings.Converters.InsertRange(0, converters);
options.SerializerSettings.ContractResolver = contractResolver;
});
}
}

@ -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<char> _charPool;
private readonly ObjectPoolProvider _objectPoolProvider;
private readonly IOptions<MvcOptions> _mvcOptions;
private readonly IOptions<MvcNewtonsoftJsonOptions> _mvcNewtonsoftJsonOptions;
public AbpNewtonsoftJsonFormatter(
ILoggerFactory loggerFactory,
ArrayPool<char> charPool,
ObjectPoolProvider objectPoolProvider,
IOptions<MvcOptions> mvcOptions,
IOptions<MvcNewtonsoftJsonOptions> mvcNewtonsoftJsonOptions)
{
_loggerFactory = loggerFactory;
_charPool = charPool;
_objectPoolProvider = objectPoolProvider;
_mvcOptions = mvcOptions;
_mvcNewtonsoftJsonOptions = mvcNewtonsoftJsonOptions;
}
Task<bool> IAbpHybridJsonInputFormatter.CanHandleAsync(Type type)
{
return Task.FromResult(true);
}
public Task<TextInputFormatter> GetTextInputFormatterAsync()
{
return Task.FromResult<TextInputFormatter>(new NewtonsoftJsonInputFormatter(
_loggerFactory.CreateLogger<NewtonsoftJsonInputFormatter>(),
_mvcNewtonsoftJsonOptions.Value.SerializerSettings,
_charPool,
_objectPoolProvider,
_mvcOptions.Value,
_mvcNewtonsoftJsonOptions.Value));
}
Task<bool> IAbpHybridJsonOutputFormatter.CanHandleAsync(Type type)
{
return Task.FromResult(true);
}
public Task<TextOutputFormatter> GetTextOutputFormatterAsync()
{
return Task.FromResult<TextOutputFormatter>(new NewtonsoftJsonOutputFormatter(
_mvcNewtonsoftJsonOptions.Value.SerializerSettings,
_charPool,
_mvcOptions.Value,
_mvcNewtonsoftJsonOptions.Value));
}
}

@ -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
{

@ -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;

@ -1,17 +0,0 @@
using Microsoft.AspNetCore.Mvc.Formatters;
using Volo.Abp.Collections;
namespace Volo.Abp.AspNetCore.Mvc.Json;
public class AbpHybridJsonFormatterOptions
{
public ITypeList<IAbpHybridJsonInputFormatter> TextInputFormatters { get; }
public ITypeList<IAbpHybridJsonInputFormatter> TextOutputFormatters { get; }
public AbpHybridJsonFormatterOptions()
{
TextInputFormatters = new TypeList<IAbpHybridJsonInputFormatter>();
TextOutputFormatters = new TypeList<IAbpHybridJsonInputFormatter>();
}
}

@ -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<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
{
return await (await GetTextInputFormatterAsync(context)).ReadRequestBodyAsync(context, encoding);
}
protected virtual async Task<TextInputFormatter> GetTextInputFormatterAsync(InputFormatterContext context)
{
var options = context.HttpContext.RequestServices.GetRequiredService<IOptions<AbpHybridJsonFormatterOptions>>().Value;
foreach (var inputFormatterType in options.TextInputFormatters)
{
var inputFormatter = context.HttpContext.RequestServices.GetRequiredService(inputFormatterType).As<IAbpHybridJsonInputFormatter>();
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;
}

@ -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<TextOutputFormatter> GetTextInputFormatter(OutputFormatterWriteContext context)
{
var options = context.HttpContext.RequestServices.GetRequiredService<IOptions<AbpHybridJsonFormatterOptions>>().Value;
foreach (var outputFormatterType in options.TextOutputFormatters)
{
var outputFormatter = context.HttpContext.RequestServices.GetRequiredService(outputFormatterType).As<IAbpHybridJsonOutputFormatter>();
if (await outputFormatter.CanHandleAsync(context.ObjectType))
{
return await outputFormatter.GetTextOutputFormatterAsync();
}
}
throw new AbpException($"The {nameof(AbpHybridJsonOutputFormatter)} can't handle '{context.ObjectType.GetFullNameWithAssemblyName()}'!");
}
}

@ -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> _jsonOptions;
private readonly IOptions<AbpSystemTextJsonSerializerOptions> _systemTextJsonSerializerOptions;
private readonly ILoggerFactory _loggerFactory;
public AbpSystemTextJsonFormatter(
IOptions<JsonOptions> jsonOptions,
IOptions<AbpSystemTextJsonSerializerOptions> systemTextJsonSerializerOptions,
ILoggerFactory loggerFactory)
{
_jsonOptions = jsonOptions;
_systemTextJsonSerializerOptions = systemTextJsonSerializerOptions;
_loggerFactory = loggerFactory;
}
Task<bool> IAbpHybridJsonInputFormatter.CanHandleAsync(Type type)
{
return Task.FromResult(!_systemTextJsonSerializerOptions.Value.UnsupportedTypes.Contains(type));
}
public virtual Task<TextInputFormatter> GetTextInputFormatterAsync()
{
return Task.FromResult<TextInputFormatter>(new SystemTextJsonInputFormatter(
_jsonOptions.Value,
_loggerFactory.CreateLogger<SystemTextJsonInputFormatter>()));
}
Task<bool> IAbpHybridJsonOutputFormatter.CanHandleAsync(Type type)
{
return Task.FromResult(!_systemTextJsonSerializerOptions.Value.UnsupportedTypes.Contains(type));
}
public Task<TextOutputFormatter> 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<TextOutputFormatter>(new SystemTextJsonOutputFormatter(jsonSerializerOptions));
}
}

@ -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<bool> CanHandleAsync(Type type);
Task<TextInputFormatter> GetTextInputFormatterAsync();
}

@ -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<bool> CanHandleAsync(Type type);
Task<TextOutputFormatter> GetTextOutputFormatterAsync();
}

@ -1,21 +0,0 @@
using Microsoft.Net.Http.Headers;
namespace Volo.Abp.AspNetCore.Mvc.Json;
/// <summary>
/// https://github.com/dotnet/aspnetcore/blob/master/src/Mvc/Mvc.NewtonsoftJson/src/MediaTypeHeaderValues.cs
/// </summary>
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();
}

@ -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<MvcOptions>(options =>
{
options.InputFormatters.RemoveType<SystemTextJsonInputFormatter>();
options.InputFormatters.Add(new AbpHybridJsonInputFormatter());
options.OutputFormatters.RemoveType<SystemTextJsonOutputFormatter>();
options.OutputFormatters.Add(new AbpHybridJsonOutputFormatter());
});
builder.Services.Configure<AbpHybridJsonFormatterOptions>(options =>
{
options.TextInputFormatters.Add<AbpSystemTextJsonFormatter>();
options.TextOutputFormatters.Add<AbpSystemTextJsonFormatter>();
});
builder.Services.AddOptions<JsonOptions>()
.Configure<IServiceProvider>((options, serviceProvider) =>
{

@ -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<Type> _ignoredTypes;
public AuditingContractResolver(List<Type> 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;
}
}

@ -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<AbpAuditingOptions> options)
{
Options = options.Value;
}
public string Serialize(object obj)
{
return JsonSerializer.Serialize(obj, CreateJsonSerializerOptions());
}
private static readonly ConcurrentDictionary<string, JsonSerializerOptions> JsonSerializerOptionsCache =
new ConcurrentDictionary<string, JsonSerializerOptions>();
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;
});
}
}

@ -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<AbpAuditingOptions> 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;
}
}

@ -30,5 +30,6 @@
<ProjectReference Include="..\Volo.Abp.Http\Volo.Abp.Http.csproj" />
<ProjectReference Include="..\Volo.Abp.IdentityModel\Volo.Abp.IdentityModel.csproj" />
<ProjectReference Include="..\Volo.Abp.Json\Volo.Abp.Json.csproj" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup>
</Project>

@ -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<AbpSystemTextJsonSerializerOptions>(options =>
{
options.UnsupportedTypes.Add(typeof(ResourceMapping));
});
Configure<AbpCliOptions>(options =>
{
options.Commands[HelpCommand.Name] = typeof(HelpCommand);

@ -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<InstallLibsService> 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<ResourceMapping>(mappingFileContent
// System.Text.Json doesn't support the property name without quotes.
var mapping = Newtonsoft.Json.JsonConvert.DeserializeObject<ResourceMapping>(mappingFileContent
.Replace("module.exports", string.Empty)
.Replace("=", string.Empty).Trim().TrimEnd(';'));

@ -10,22 +10,6 @@ public static class AbpApiProxyScriptingConfiguration
static AbpApiProxyScriptingConfiguration()
{
PropertyNameGenerator = propertyInfo =>
{
var jsonPropertyNameAttribute = propertyInfo.GetSingleAttributeOrNull<System.Text.Json.Serialization.JsonPropertyNameAttribute>(true);
if (jsonPropertyNameAttribute != null)
{
return jsonPropertyNameAttribute.Name;
}
var jsonPropertyAttribute = propertyInfo.GetSingleAttributeOrNull<Newtonsoft.Json.JsonPropertyAttribute>(true);
if (jsonPropertyAttribute != null)
{
return jsonPropertyAttribute.PropertyName;
}
return null;
};
propertyInfo.GetSingleAttributeOrNull<System.Text.Json.Serialization.JsonPropertyNameAttribute>()?.Name;
}
}

@ -5,7 +5,7 @@
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<PackageId>Volo.Abp.Json.Core</PackageId>
<PackageId>Volo.Abp.Json.Abstractions</PackageId>
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>

@ -2,7 +2,7 @@
namespace Volo.Abp.Json;
public class AbpJsonCoreModule : AbpModule
public class AbpJsonAbstractionsModule : AbpModule
{
}

@ -0,0 +1,9 @@
namespace Volo.Abp.Json;
public class AbpJsonOptions
{
/// <summary>
/// Used to set default value for the DateTimeFormat.
/// </summary>
public string DefaultDateTimeFormat { get; set; }
}

@ -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<AbpJsonOptions> 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<T>([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<T>(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()}'!");
}
}

@ -1,18 +0,0 @@
using Volo.Abp.Collections;
namespace Volo.Abp.Json;
public class AbpJsonOptions
{
/// <summary>
/// Used to set default value for the DateTimeFormat.
/// </summary>
public string DefaultDateTimeFormat { get; set; }
public ITypeList<IJsonSerializerProvider> Providers { get; }
public AbpJsonOptions()
{
Providers = new TypeList<IJsonSerializerProvider>();
}
}

@ -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<T>(string jsonString, bool camelCase = true);
object Deserialize(Type type, string jsonString, bool camelCase = true);
}

@ -15,7 +15,7 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.Json.Core\Volo.Abp.Json.Core.csproj" />
<ProjectReference Include="..\Volo.Abp.Json.Abstractions\Volo.Abp.Json.Abstractions.csproj" />
<ProjectReference Include="..\Volo.Abp.Timing\Volo.Abp.Timing.csproj" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup>

@ -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<DisableDateTimeNormalizationAttribute>(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;
}
}

@ -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<AbpJsonIsoDateTimeConverter> _dateTimeConverter;
public AbpDefaultContractResolver(IServiceProvider serviceProvider)
{
_dateTimeConverter = new Lazy<AbpJsonIsoDateTimeConverter>(
serviceProvider.GetRequiredService<AbpJsonIsoDateTimeConverter>,
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;
}
}

@ -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<DisableDateTimeNormalizationAttribute>(member) == null;
}
}

@ -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<AbpJsonOptions>(options =>
{
options.Providers.Add<AbpNewtonsoftJsonSerializerProvider>();
});
context.Services.AddOptions<AbpNewtonsoftJsonSerializerOptions>()
.Configure<AbpCamelCasePropertyNamesContractResolver>((options, contractResolver) =>
{

@ -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<AbpNewtonsoftJsonSerializerOptions> Options { get; }
public AbpNewtonsoftJsonSerializerProvider(IOptions<AbpNewtonsoftJsonSerializerOptions> options)
public AbpNewtonsoftJsonSerializer(IServiceProvider serviceProvider, IOptions<AbpNewtonsoftJsonSerializerOptions> 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<object, JsonSerializerSettings> JsonSerializerOptionsCache = new ConcurrentDictionary<object, JsonSerializerSettings>();
private static readonly ConcurrentDictionary<object, JsonSerializerSettings> JsonSerializerOptionsCache =
new ConcurrentDictionary<object, JsonSerializerSettings>();
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<AbpCamelCasePropertyNamesContractResolver>();
// }
settings.ContractResolver = camelCase
? ServiceProvider.GetRequiredService<AbpCamelCasePropertyNamesContractResolver>()
: ServiceProvider.GetRequiredService<AbpDefaultContractResolver>();
if (indented)
{

@ -15,7 +15,7 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.Json.Core\Volo.Abp.Json.Core.csproj" />
<ProjectReference Include="..\Volo.Abp.Json.Abstractions\Volo.Abp.Json.Abstractions.csproj" />
<ProjectReference Include="..\Volo.Abp.Timing\Volo.Abp.Timing.csproj" />
<PackageReference Include="System.Text.Json" Version="$(MicrosoftAspNetCorePackageVersion)" />
</ItemGroup>

@ -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<AbpJsonOptions>(options =>
{
options.Providers.Add<AbpSystemTextJsonSerializerProvider>();
});
context.Services.AddOptions<AbpSystemTextJsonSerializerOptions>()
.Configure<IServiceProvider>((options, serviceProvider) =>
{

@ -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<AbpSystemTextJsonSerializerOptions> options)
public AbpSystemTextJsonSerializer(IOptions<AbpSystemTextJsonSerializerOptions> 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<object, JsonSerializerOptions> JsonSerializerOptionsCache = new ConcurrentDictionary<object, JsonSerializerOptions>();
private static readonly ConcurrentDictionary<object, JsonSerializerOptions> JsonSerializerOptionsCache =
new ConcurrentDictionary<object, JsonSerializerOptions>();
protected virtual JsonSerializerOptions CreateJsonSerializerOptions(bool camelCase = true, bool indented = false)
{

@ -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();
}
}

@ -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<ExtensibleObject>(), x => x.ExtraProperties, () => (ExtraPropertyDictionary)value);
};
}
}
}

@ -15,7 +15,6 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.Json.Newtonsoft\Volo.Abp.Json.Newtonsoft.csproj" />
<ProjectReference Include="..\Volo.Abp.Json.SystemTextJson\Volo.Abp.Json.SystemTextJson.csproj" />
</ItemGroup>

@ -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
{

@ -25,7 +25,6 @@
<ItemGroup>
<ProjectReference Include="..\..\src\Volo.Abp.AspNetCore.Mvc.UI\Volo.Abp.AspNetCore.Mvc.UI.csproj" />
<ProjectReference Include="..\..\src\Volo.Abp.AspNetCore.Mvc.NewtonsoftJson\Volo.Abp.AspNetCore.Mvc.NewtonsoftJson.csproj" />
<ProjectReference Include="..\..\src\Volo.Abp.Autofac\Volo.Abp.Autofac.csproj" />
<ProjectReference Include="..\Volo.Abp.AspNetCore.Tests\Volo.Abp.AspNetCore.Tests.csproj" />
<ProjectReference Include="..\Volo.Abp.MemoryDb.Tests\Volo.Abp.MemoryDb.Tests.csproj" />

@ -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

@ -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<AbpSystemTextJsonSerializerOptions>(options =>
{
options.UnsupportedTypes.Add<GetDateTimeKindModel>();
options.UnsupportedTypes.Add<GetDateTimeKindModel.GetDateTimeKindInnerModel>();
});
services.Configure<IOptions<Newtonsoft_ModelBindingController_Utc_Tests>>(x =>
{
});
base.ConfigureServices(context, services);
}
}
public class Newtonsoft_ModelBindingController_Local_Tests : ModelBindingController_Local_Tests
{
protected override void ConfigureServices(HostBuilderContext context, IServiceCollection services)
{
services.Configure<AbpSystemTextJsonSerializerOptions>(options =>
{
options.UnsupportedTypes.Add<GetDateTimeKindModel>();
options.UnsupportedTypes.Add<GetDateTimeKindModel.GetDateTimeKindInnerModel>();
});
base.ConfigureServices(context, services);
}
}

@ -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<AbpAspNetCoreMvcTestModule>(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);
});

@ -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<JsonNetAuditSerializer>();
_jsonAuditSerializer = GetRequiredService<JsonAuditSerializer>();
}
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; }

@ -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<IJsonSerializer>();
}
protected override void AfterAddApplication(IServiceCollection services)
{
services.Configure<AbpSystemTextJsonSerializerOptions>(options =>
{
options.UnsupportedTypes.Add<MyClass1>();
options.JsonSerializerOptions.Converters.Add(new SystemTextJsonConverter());
});
services.Configure<AbpNewtonsoftJsonSerializerOptions>(options =>
{
options.Converters.Add<NewtonsoftJsonConverter>();
});
}
[Fact]
public void NewtonsoftSerialize_Test()
{
var json = _jsonSerializer.Serialize(new MyClass1
{
Providers = new List<MyClass3>
{
new MyClass3()
}
});
json.ShouldContain("Newtonsoft");
}
[Fact]
public void SystemTextJsonSerialize_Test()
{
var json = _jsonSerializer.Serialize(new MyClass2
{
Providers = new List<MyClass3>
{
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<MyClassWithDictionary>(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<MyClass3> Providers { get; set; }
}
public class MyClass2
{
public string Provider { get; set; }
public List<MyClass3> Providers { get; set; }
}
public class MyClass3
{
public string Provider { get; set; }
}
public class MyClassWithDictionary
{
public Dictionary<string, string> Properties { get; set; }
public MyClassWithDictionary()
{
Properties = new Dictionary<string, string>();
}
}
class NewtonsoftJsonConverter : JsonConverter<MyClass1>, 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<MyClass2>, 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);
}
}
}

@ -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<AbpSystemTextJsonSerializerProvider>();
JsonSerializer = GetRequiredService<AbpSystemTextJsonSerializer>();
}
public class TestExtensibleObjectClass : ExtensibleObject

@ -10,7 +10,7 @@ public class ExtensibleObjectModifiers_Tests : AbpJsonTestBase
[Fact]
public void Should_Modify_Object()
{
var jsonSerializer = GetRequiredService<AbpSystemTextJsonSerializerProvider>();
var jsonSerializer = GetRequiredService<AbpSystemTextJsonSerializer>();
var extensibleObject = jsonSerializer.Deserialize<ExtensibleObject>("{\"ExtraProperties\": {\"Test-Key\":\"Test-Value\"}}");

@ -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",

Loading…
Cancel
Save