mirror of https://github.com/abpframework/abp.git
12 changed files with 195 additions and 168 deletions
@ -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; |
|||
} |
|||
} |
|||
} |
|||
@ -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(); |
|||
} |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
} |
|||
@ -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>(); |
|||
} |
|||
} |
|||
} |
|||
@ -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; } |
|||
} |
|||
} |
|||
} |
|||
@ -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…
Reference in new issue