Enhanced SystemTextJsonSupportTypeMatcher.

pull/5952/head
maliming 5 years ago
parent e0204e9576
commit dee8f22055

@ -10,7 +10,8 @@ namespace Volo.Abp.Json.SystemTextJson
{ {
public class SystemTextJsonSupportTypeMatcher : ITransientDependency public class SystemTextJsonSupportTypeMatcher : ITransientDependency
{ {
private static readonly ConcurrentBag<Type> CacheTypes = new ConcurrentBag<Type>(); private static readonly ConcurrentBag<Type> SupportedTypesCache = new ConcurrentBag<Type>();
private static readonly ConcurrentBag<Type> UnsupportedTypesCache = new ConcurrentBag<Type>();
private readonly SystemTextJsonSupportTypeMatcherOptions _options; private readonly SystemTextJsonSupportTypeMatcherOptions _options;
@ -21,25 +22,83 @@ namespace Volo.Abp.Json.SystemTextJson
public bool Match(Type type) public bool Match(Type type)
{ {
if (_options.UnsupportedTypes.Any(x => x == type)) if (UnsupportedTypesCache.Contains(type))
{ {
return false; return false;
} }
if (CacheTypes.Contains(type)) if (SupportedTypesCache.Contains(type))
{ {
return true;
}
if (_options.UnsupportedTypes.Any(x => x == type))
{
UnsupportedTypesCache.Add(type);
return false; return false;
} }
if (type.IsGenericType)
{
foreach (var genericArgument in type.GetGenericArguments())
{
if (!TypeHelper.IsPrimitiveExtended(genericArgument, includeNullables: true, includeEnums: true))
{
if (!Match(genericArgument))
{
return false;
}
}
else
{
if (_options.UnsupportedTypes.Any(x => x == genericArgument))
{
UnsupportedTypesCache.Add(genericArgument);
return false;
}
}
}
return true;
}
if (type.IsArray)
{
var elementType = type.GetElementType();
if (!TypeHelper.IsPrimitiveExtended(elementType, includeNullables: true, includeEnums: true))
{
if (!Match(elementType))
{
return false;
}
}
else
{
if (_options.UnsupportedTypes.Any(x => x == elementType))
{
UnsupportedTypesCache.Add(elementType);
return false;
}
}
return true;
}
if (TypeHelper.IsPrimitiveExtended(type, includeNullables: true, includeEnums: true))
{
return true;
}
if (type.GetCustomAttributes(true).Any(x => _options.UnsupportedAttributes.Any(a => a == x.GetType()))) if (type.GetCustomAttributes(true).Any(x => _options.UnsupportedAttributes.Any(a => a == x.GetType())))
{ {
CacheTypes.Add(type); UnsupportedTypesCache.Add(type);
return false; return false;
} }
if (type.DeclaringType != null && type.DeclaringType.GetCustomAttributes(true).Any(x => _options.UnsupportedAttributes.Any(a => a == x.GetType()))) if (type.DeclaringType != null && type.DeclaringType.GetCustomAttributes(true).Any(x => _options.UnsupportedAttributes.Any(a => a == x.GetType())))
{ {
CacheTypes.Add(type); UnsupportedTypesCache.Add(type);
return false; return false;
} }
@ -47,19 +106,76 @@ namespace Volo.Abp.Json.SystemTextJson
{ {
if (propertyInfo.IsDefined(typeof(DisableDateTimeNormalizationAttribute), true)) if (propertyInfo.IsDefined(typeof(DisableDateTimeNormalizationAttribute), true))
{ {
CacheTypes.Add(type); UnsupportedTypesCache.Add(type);
return false;
}
if (_options.UnsupportedTypes.Any(x => x == propertyInfo.PropertyType))
{
UnsupportedTypesCache.Add(propertyInfo.PropertyType);
return false; return false;
} }
if (!TypeHelper.IsPrimitiveExtended(type, includeNullables: true, includeEnums: true)) if (propertyInfo.PropertyType.IsGenericType)
{
foreach (var genericArgument in propertyInfo.PropertyType.GetGenericArguments())
{
if (!TypeHelper.IsPrimitiveExtended(genericArgument, includeNullables: true, includeEnums: true))
{
if (!Match(genericArgument))
{
return false;
}
}
else
{
if (_options.UnsupportedTypes.Any(x => x == genericArgument))
{
UnsupportedTypesCache.Add(genericArgument);
return false;
}
}
}
}
if (propertyInfo.PropertyType.IsArray)
{
var elementType = propertyInfo.PropertyType.GetElementType();
if (!TypeHelper.IsPrimitiveExtended(elementType, includeNullables: true, includeEnums: true))
{
if (!Match(elementType))
{
return false;
}
}
else
{
if (_options.UnsupportedTypes.Any(x => x == elementType))
{
UnsupportedTypesCache.Add(elementType);
return false;
}
}
}
if (!TypeHelper.IsPrimitiveExtended(propertyInfo.PropertyType, includeNullables: true, includeEnums: true))
{ {
if (!Match(propertyInfo.PropertyType)) if (!Match(propertyInfo.PropertyType))
{ {
return false; return false;
} }
} }
else
{
if (_options.UnsupportedTypes.Any(x => x == propertyInfo.PropertyType))
{
UnsupportedTypesCache.Add(propertyInfo.PropertyType);
return false;
}
}
} }
SupportedTypesCache.Add(type);
return true; return true;
} }
} }

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Shouldly; using Shouldly;
using Volo.Abp.Json.SystemTextJson; using Volo.Abp.Json.SystemTextJson;
@ -16,6 +17,7 @@ namespace Volo.Abp.Json
services.Configure<SystemTextJsonSupportTypeMatcherOptions>(options => services.Configure<SystemTextJsonSupportTypeMatcherOptions>(options =>
{ {
options.UnsupportedTypes.Add<MyClass7>(); options.UnsupportedTypes.Add<MyClass7>();
options.UnsupportedTypes.Add<byte>();
}); });
base.AfterAddApplication(services); base.AfterAddApplication(services);
@ -38,6 +40,18 @@ namespace Volo.Abp.Json
_systemTextJsonSupportTypeMatcher.Match(typeof(MyClass6)).ShouldBeTrue(); _systemTextJsonSupportTypeMatcher.Match(typeof(MyClass6)).ShouldBeTrue();
_systemTextJsonSupportTypeMatcher.Match(typeof(MyClass7)).ShouldBeFalse(); _systemTextJsonSupportTypeMatcher.Match(typeof(MyClass7)).ShouldBeFalse();
_systemTextJsonSupportTypeMatcher.Match(typeof(MyClass8)).ShouldBeFalse();
_systemTextJsonSupportTypeMatcher.Match(typeof(MyClass9)).ShouldBeFalse();
_systemTextJsonSupportTypeMatcher.Match(typeof(string)).ShouldBeTrue();
_systemTextJsonSupportTypeMatcher.Match(typeof(string[])).ShouldBeTrue();
_systemTextJsonSupportTypeMatcher.Match(typeof(int)).ShouldBeTrue();
_systemTextJsonSupportTypeMatcher.Match(typeof(byte)).ShouldBeFalse();
_systemTextJsonSupportTypeMatcher.Match(typeof(Dictionary<byte, byte>)).ShouldBeFalse();
_systemTextJsonSupportTypeMatcher.Match(typeof(Dictionary<string, MyClass10>)).ShouldBeFalse();
} }
[DisableDateTimeNormalization] [DisableDateTimeNormalization]
@ -79,5 +93,21 @@ namespace Volo.Abp.Json
{ {
public DateTime Prop1 { get; set; } public DateTime Prop1 { get; set; }
} }
class MyClass8
{
public MyClass10[] Prop1 { get; set; }
}
class MyClass9
{
public Dictionary<string, MyClass10> Prop1 { get; set; }
}
class MyClass10
{
[DisableDateTimeNormalization]
public DateTime Prop1 { get; set; }
}
} }
} }

Loading…
Cancel
Save