Browse Source

Refactor.

pull/5952/head
maliming 6 years ago
parent
commit
bffccb8f66
  1. 3
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonInputFormatter.cs
  2. 4
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonOutputFormatter.cs
  3. 2
      framework/src/Volo.Abp.Auditing/Volo.Abp.Auditing.csproj
  4. 28
      framework/src/Volo.Abp.Json/Volo/Abp/Json/AbpHybridJsonSerializer.cs
  5. 4
      framework/src/Volo.Abp.Json/Volo/Abp/Json/AbpJsonModule.cs
  6. 13
      framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/SystemTextJsonSerializerProvider.cs
  7. 66
      framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/SystemTextJsonSupportTypeMatcher.cs
  8. 18
      framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/SystemTextJsonSupportTypeMatcherOptions.cs
  9. 62
      framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/SystemTextJsonSupportTypes.cs
  10. 15
      framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/SystemTextJsonSupportTypesOptions.cs
  11. 83
      framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/SystemTextJsonSupportTypeMatcher_Tests.cs
  12. 65
      framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/SystemTextJsonSupportTypes_Tests.cs

3
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonInputFormatter.cs

@ -25,7 +25,8 @@ namespace Volo.Abp.AspNetCore.Mvc.Json
private TextInputFormatter GetTextInputFormatter(InputFormatterContext context) private TextInputFormatter GetTextInputFormatter(InputFormatterContext context)
{ {
if (context.HttpContext.RequestServices.GetRequiredService<SystemTextJsonSupportTypes>().CanHandle(context.ModelType)) var typesMatcher = context.HttpContext.RequestServices.GetRequiredService<SystemTextJsonSupportTypeMatcher>();
if (typesMatcher.Match(context.ModelType))
{ {
return context.HttpContext.RequestServices.GetRequiredService<SystemTextJsonInputFormatter>(); return context.HttpContext.RequestServices.GetRequiredService<SystemTextJsonInputFormatter>();
} }

4
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonOutputFormatter.cs

@ -12,6 +12,7 @@ namespace Volo.Abp.AspNetCore.Mvc.Json
{ {
SupportedEncodings.Add(Encoding.UTF8); SupportedEncodings.Add(Encoding.UTF8);
SupportedEncodings.Add(Encoding.Unicode); SupportedEncodings.Add(Encoding.Unicode);
SupportedMediaTypes.Add(MediaTypeHeaderValues.ApplicationJson); SupportedMediaTypes.Add(MediaTypeHeaderValues.ApplicationJson);
SupportedMediaTypes.Add(MediaTypeHeaderValues.TextJson); SupportedMediaTypes.Add(MediaTypeHeaderValues.TextJson);
SupportedMediaTypes.Add(MediaTypeHeaderValues.ApplicationAnyJsonSyntax); SupportedMediaTypes.Add(MediaTypeHeaderValues.ApplicationAnyJsonSyntax);
@ -24,7 +25,8 @@ namespace Volo.Abp.AspNetCore.Mvc.Json
private TextOutputFormatter GetTextInputFormatter(OutputFormatterWriteContext context) private TextOutputFormatter GetTextInputFormatter(OutputFormatterWriteContext context)
{ {
if (context.HttpContext.RequestServices.GetRequiredService<SystemTextJsonSupportTypes>().CanHandle(context.ObjectType)) var typesMatcher = context.HttpContext.RequestServices.GetRequiredService<SystemTextJsonSupportTypeMatcher>();
if (typesMatcher.Match(context.ObjectType))
{ {
return context.HttpContext.RequestServices.GetRequiredService<SystemTextJsonOutputFormatter>(); return context.HttpContext.RequestServices.GetRequiredService<SystemTextJsonOutputFormatter>();
} }

2
framework/src/Volo.Abp.Auditing/Volo.Abp.Auditing.csproj

@ -22,7 +22,7 @@
<ProjectReference Include="..\Volo.Abp.Threading\Volo.Abp.Threading.csproj" /> <ProjectReference Include="..\Volo.Abp.Threading\Volo.Abp.Threading.csproj" />
<ProjectReference Include="..\Volo.Abp.Timing\Volo.Abp.Timing.csproj" /> <ProjectReference Include="..\Volo.Abp.Timing\Volo.Abp.Timing.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup> </ItemGroup>

28
framework/src/Volo.Abp.Json/Volo/Abp/Json/AbpHybridJsonSerializer.cs

@ -1,5 +1,4 @@
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
@ -7,21 +6,16 @@ using Volo.Abp.DependencyInjection;
namespace Volo.Abp.Json namespace Volo.Abp.Json
{ {
public class AbpHybridJsonSerializer : IJsonSerializer, ISingletonDependency public class AbpHybridJsonSerializer : IJsonSerializer, ITransientDependency
{ {
private readonly Lazy<List<IJsonSerializerProvider>> _lazyProviders; protected AbpJsonOptions Options { get; }
public List<IJsonSerializerProvider> Providers => _lazyProviders.Value;
protected IServiceProvider ServiceProvider { get; }
public AbpHybridJsonSerializer(IOptions<AbpJsonOptions> options, IServiceProvider serviceProvider) public AbpHybridJsonSerializer(IOptions<AbpJsonOptions> options, IServiceProvider serviceProvider)
{ {
_lazyProviders = new Lazy<List<IJsonSerializerProvider>>( Options = options.Value;
() => options.Value ServiceProvider = serviceProvider;
.Providers
.Select(c => serviceProvider.GetRequiredService(c) as IJsonSerializerProvider)
.Reverse()
.ToList(),
true
);
} }
public string Serialize(object obj, bool camelCase = true, bool indented = false) public string Serialize(object obj, bool camelCase = true, bool indented = false)
@ -44,12 +38,16 @@ namespace Volo.Abp.Json
protected virtual IJsonSerializerProvider GetSerializerProvider(Type type) protected virtual IJsonSerializerProvider GetSerializerProvider(Type type)
{ {
foreach (var provider in Providers.Where(provider => provider.CanHandle(type))) foreach (var providerType in Options.Providers.Reverse())
{ {
return provider; 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()} types!"); throw new AbpException($"There is no IJsonSerializerProvider that can handle '{type.GetFullNameWithAssemblyName()}'!");
} }
} }
} }

4
framework/src/Volo.Abp.Json/Volo/Abp/Json/AbpJsonModule.cs

@ -23,9 +23,9 @@ namespace Volo.Abp.Json
options.Providers.Add<SystemTextJsonSerializerProvider>(); options.Providers.Add<SystemTextJsonSerializerProvider>();
}); });
Configure<SystemTextJsonSupportTypesOptions>(options => Configure<SystemTextJsonSupportTypeMatcherOptions>(options =>
{ {
options.IgnoreAttributes.Add<DisableDateTimeNormalizationAttribute>(); options.UnsupportedAttributes.Add<DisableDateTimeNormalizationAttribute>();
}); });
} }
} }

13
framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/SystemTextJsonSerializerProvider.cs

@ -2,25 +2,26 @@
using System.Text.Json; using System.Text.Json;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.Json.SystemTextJson;
namespace Volo.Abp.Json namespace Volo.Abp.Json.SystemTextJson
{ {
public class SystemTextJsonSerializerProvider : IJsonSerializerProvider, ITransientDependency public class SystemTextJsonSerializerProvider : IJsonSerializerProvider, ITransientDependency
{ {
protected AbpSystemTextJsonSerializerOptions Options { get; } protected AbpSystemTextJsonSerializerOptions Options { get; }
protected SystemTextJsonSupportTypes SystemTextJsonSupportTypes { get; } protected SystemTextJsonSupportTypeMatcher SystemTextJsonSupportTypeMatcher { get; }
public SystemTextJsonSerializerProvider(IOptions<AbpSystemTextJsonSerializerOptions> options, SystemTextJsonSupportTypes systemTextJsonSupportTypes) public SystemTextJsonSerializerProvider(
IOptions<AbpSystemTextJsonSerializerOptions> options,
SystemTextJsonSupportTypeMatcher systemTextJsonSupportTypeMatcher)
{ {
SystemTextJsonSupportTypes = systemTextJsonSupportTypes; SystemTextJsonSupportTypeMatcher = systemTextJsonSupportTypeMatcher;
Options = options.Value; Options = options.Value;
} }
public bool CanHandle(Type type) public bool CanHandle(Type type)
{ {
return SystemTextJsonSupportTypes.CanHandle(type); return SystemTextJsonSupportTypeMatcher.Match(type);
} }
public string Serialize(object obj, bool camelCase = true, bool indented = false) public string Serialize(object obj, bool camelCase = true, bool indented = false)

66
framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/SystemTextJsonSupportTypeMatcher.cs

@ -0,0 +1,66 @@
using System;
using System.Collections.Concurrent;
using System.Linq;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Reflection;
using Volo.Abp.Timing;
namespace Volo.Abp.Json.SystemTextJson
{
public class SystemTextJsonSupportTypeMatcher : ITransientDependency
{
private static readonly ConcurrentBag<Type> CacheTypes = new ConcurrentBag<Type>();
private readonly SystemTextJsonSupportTypeMatcherOptions _options;
public SystemTextJsonSupportTypeMatcher(IOptions<SystemTextJsonSupportTypeMatcherOptions> options)
{
_options = options.Value;
}
public bool Match(Type type)
{
if (_options.UnsupportedTypes.Any(x => x == type))
{
return false;
}
if (CacheTypes.Contains(type))
{
return false;
}
if (type.GetCustomAttributes(true).Any(x => _options.UnsupportedAttributes.Any(a => a == x.GetType())))
{
CacheTypes.Add(type);
return false;
}
if (type.DeclaringType != null && type.DeclaringType.GetCustomAttributes(true).Any(x => _options.UnsupportedAttributes.Any(a => a == x.GetType())))
{
CacheTypes.Add(type);
return false;
}
foreach (var propertyInfo in type.GetProperties())
{
if (propertyInfo.IsDefined(typeof(DisableDateTimeNormalizationAttribute), true))
{
CacheTypes.Add(type);
return false;
}
if (!TypeHelper.IsPrimitiveExtended(type, includeNullables: true, includeEnums: true))
{
if (!Match(propertyInfo.PropertyType))
{
return false;
}
}
}
return true;
}
}
}

18
framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/SystemTextJsonSupportTypeMatcherOptions.cs

@ -0,0 +1,18 @@
using System;
using Volo.Abp.Collections;
namespace Volo.Abp.Json.SystemTextJson
{
public class SystemTextJsonSupportTypeMatcherOptions
{
public ITypeList<Attribute> UnsupportedAttributes { get; }
public ITypeList UnsupportedTypes { get; }
public SystemTextJsonSupportTypeMatcherOptions()
{
UnsupportedAttributes = new TypeList<Attribute>();
UnsupportedTypes = new TypeList();
}
}
}

62
framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/SystemTextJsonSupportTypes.cs

@ -1,62 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Reflection;
using Volo.Abp.Timing;
namespace Volo.Abp.Json.SystemTextJson
{
public class SystemTextJsonSupportTypes : ITransientDependency
{
private static readonly List<Type> CacheTypes = new List<Type>();
private readonly SystemTextJsonSupportTypesOptions Options;
public SystemTextJsonSupportTypes(IOptions<SystemTextJsonSupportTypesOptions> options)
{
Options = options.Value;
}
public bool CanHandle(Type type)
{
if (CacheTypes.Any(x => x == type))
{
return false;
}
if (type.GetCustomAttributes(true).Any(x => Options.IgnoreAttributes.Any(a => a == x.GetType())))
{
CacheTypes.Add(type);
return false;
}
if (type.DeclaringType != null && type.DeclaringType.GetCustomAttributes(true).Any(x => Options.IgnoreAttributes.Any(a => a == x.GetType())))
{
CacheTypes.Add(type.DeclaringType);
return false;
}
foreach (var propertyInfo in type.GetProperties())
{
if (propertyInfo.IsDefined(typeof(DisableDateTimeNormalizationAttribute), true))
{
CacheTypes.Add(propertyInfo.GetType());
return false;
}
if (!TypeHelper.IsPrimitiveExtended(type))
{
if (!CanHandle(propertyInfo.PropertyType))
{
CacheTypes.Add(propertyInfo.PropertyType);
return false;
}
}
}
return true;
}
}
}

15
framework/src/Volo.Abp.Json/Volo/Abp/Json/SystemTextJson/SystemTextJsonSupportTypesOptions.cs

@ -1,15 +0,0 @@
using System;
using Volo.Abp.Collections;
namespace Volo.Abp.Json.SystemTextJson
{
public class SystemTextJsonSupportTypesOptions
{
public ITypeList<Attribute> IgnoreAttributes;
public SystemTextJsonSupportTypesOptions()
{
IgnoreAttributes = new TypeList<Attribute>();
}
}
}

83
framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/SystemTextJsonSupportTypeMatcher_Tests.cs

@ -0,0 +1,83 @@
using System;
using Microsoft.Extensions.DependencyInjection;
using Shouldly;
using Volo.Abp.Json.SystemTextJson;
using Volo.Abp.Timing;
using Xunit;
namespace Volo.Abp.Json
{
public class SystemTextJsonSupportTypeMatcher_Tests : AbpJsonTestBase
{
private readonly SystemTextJsonSupportTypeMatcher _systemTextJsonSupportTypeMatcher;
protected override void AfterAddApplication(IServiceCollection services)
{
services.Configure<SystemTextJsonSupportTypeMatcherOptions>(options =>
{
options.UnsupportedTypes.Add<MyClass7>();
});
base.AfterAddApplication(services);
}
public SystemTextJsonSupportTypeMatcher_Tests()
{
_systemTextJsonSupportTypeMatcher = GetRequiredService<SystemTextJsonSupportTypeMatcher>();
}
[Fact]
public void CanHandle_Test()
{
_systemTextJsonSupportTypeMatcher.Match(typeof(MyClass)).ShouldBeFalse();
_systemTextJsonSupportTypeMatcher.Match(typeof(MyClass2)).ShouldBeFalse();
_systemTextJsonSupportTypeMatcher.Match(typeof(MyClass3)).ShouldBeFalse();
_systemTextJsonSupportTypeMatcher.Match(typeof(MyClass4)).ShouldBeFalse();
_systemTextJsonSupportTypeMatcher.Match(typeof(MyClass5)).ShouldBeTrue();
_systemTextJsonSupportTypeMatcher.Match(typeof(MyClass6)).ShouldBeTrue();
_systemTextJsonSupportTypeMatcher.Match(typeof(MyClass7)).ShouldBeFalse();
}
[DisableDateTimeNormalization]
class MyClass
{
public DateTime Prop1 { get; set; }
}
class MyClass2
{
[DisableDateTimeNormalization]
public DateTime Prop1 { get; set; }
}
class MyClass3
{
public MyClass4 Prop1 { get; set; }
}
class MyClass4
{
[DisableDateTimeNormalization]
public DateTime Prop1 { get; set; }
}
class MyClass5
{
public DateTime Prop1 { get; set; }
public MyClass6 Prop2 { get; set; }
}
class MyClass6
{
public DateTime Prop1 { get; set; }
}
class MyClass7
{
public DateTime Prop1 { get; set; }
}
}
}

65
framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/SystemTextJsonSupportTypes_Tests.cs

@ -1,65 +0,0 @@
using System;
using Shouldly;
using Volo.Abp.Json.SystemTextJson;
using Volo.Abp.Timing;
using Xunit;
namespace Volo.Abp.Json
{
public class SystemTextJsonSupportTypes_Tests : AbpJsonTestBase
{
private readonly SystemTextJsonSupportTypes _systemTextJsonSupportTypes;
public SystemTextJsonSupportTypes_Tests()
{
_systemTextJsonSupportTypes = GetRequiredService<SystemTextJsonSupportTypes>();
}
[Fact]
public void Test()
{
_systemTextJsonSupportTypes.CanHandle(typeof(MyClass)).ShouldBeFalse();
_systemTextJsonSupportTypes.CanHandle(typeof(MyClass2)).ShouldBeFalse();
_systemTextJsonSupportTypes.CanHandle(typeof(MyClass3)).ShouldBeFalse();
_systemTextJsonSupportTypes.CanHandle(typeof(MyClass4)).ShouldBeFalse();
_systemTextJsonSupportTypes.CanHandle(typeof(MyClass5)).ShouldBeTrue();
_systemTextJsonSupportTypes.CanHandle(typeof(MyClass6)).ShouldBeTrue();
}
[DisableDateTimeNormalization]
class MyClass
{
public DateTime Prop1 { get; set; }
}
class MyClass2
{
[DisableDateTimeNormalization]
public DateTime Prop1 { get; set; }
}
class MyClass3
{
public MyClass4 Prop1 { get; set; }
}
class MyClass4
{
[DisableDateTimeNormalization]
public DateTime Prop1 { get; set; }
}
class MyClass5
{
public DateTime Prop1 { get; set; }
public MyClass6 Prop2 { get; set; }
}
class MyClass6
{
public DateTime Prop1 { get; set; }
}
}
}
Loading…
Cancel
Save