-Fixed error when deserializing null value into ConcurrentDictionary
This commit is contained in:
@@ -61,6 +61,20 @@ namespace Newtonsoft.Json.Tests.Serialization
|
||||
[TestFixture]
|
||||
public class JsonSerializerCollectionsTests : TestFixtureBase
|
||||
{
|
||||
#if !(NET35 || NET20 || PORTABLE || PORTABLE40) || NETSTANDARD2_0
|
||||
[Test]
|
||||
public void DeserializeConcurrentDictionaryWithNullValue()
|
||||
{
|
||||
const string key = "id";
|
||||
|
||||
var jsonValue = $"{{\"{key}\":null}}";
|
||||
|
||||
var deserializedObject = JsonConvert.DeserializeObject<ConcurrentDictionary<string, string>>(jsonValue);
|
||||
|
||||
Assert.IsNull(deserializedObject[key]);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !(NET20 || NET35)
|
||||
[Test]
|
||||
public void SerializeConcurrentQueue()
|
||||
|
||||
@@ -900,7 +900,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
case "System.Collections.Concurrent.ConcurrentQueue`1":
|
||||
case "System.Collections.Concurrent.ConcurrentStack`1":
|
||||
case "System.Collections.Concurrent.ConcurrentBag`1":
|
||||
case "System.Collections.Concurrent.ConcurrentDictionary`2":
|
||||
case JsonTypeReflector.ConcurrentDictionaryTypeName:
|
||||
case "System.Collections.ObjectModel.ObservableCollection`1":
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -127,10 +127,22 @@ namespace Newtonsoft.Json.Serialization
|
||||
{
|
||||
CreatedType = typeof(Dictionary<,>).MakeGenericType(keyType, valueType);
|
||||
}
|
||||
else if (underlyingType.IsGenericType())
|
||||
{
|
||||
// ConcurrentDictionary<,> + IDictionary setter + null value = error
|
||||
// wrap to use generic setter
|
||||
// https://github.com/JamesNK/Newtonsoft.Json/issues/1582
|
||||
Type typeDefinition = underlyingType.GetGenericTypeDefinition();
|
||||
if (typeDefinition.FullName == JsonTypeReflector.ConcurrentDictionaryTypeName)
|
||||
{
|
||||
ShouldCreateWrapper = true;
|
||||
}
|
||||
}
|
||||
|
||||
#if HAVE_READ_ONLY_COLLECTIONS
|
||||
IsReadOnlyOrFixedSize = ReflectionUtils.InheritsGenericDefinition(underlyingType, typeof(ReadOnlyDictionary<,>));
|
||||
#endif
|
||||
|
||||
}
|
||||
#if HAVE_READ_ONLY_COLLECTIONS
|
||||
else if (ReflectionUtils.ImplementsGenericDefinition(underlyingType, typeof(IReadOnlyDictionary<,>), out _genericCollectionDefinitionType))
|
||||
@@ -172,7 +184,10 @@ namespace Newtonsoft.Json.Serialization
|
||||
#endif
|
||||
}
|
||||
|
||||
ShouldCreateWrapper = !typeof(IDictionary).IsAssignableFrom(CreatedType);
|
||||
if (!typeof(IDictionary).IsAssignableFrom(CreatedType))
|
||||
{
|
||||
ShouldCreateWrapper = true;
|
||||
}
|
||||
|
||||
DictionaryKeyType = keyType;
|
||||
DictionaryValueType = valueType;
|
||||
|
||||
@@ -56,6 +56,8 @@ namespace Newtonsoft.Json.Serialization
|
||||
public const string ShouldSerializePrefix = "ShouldSerialize";
|
||||
public const string SpecifiedPostfix = "Specified";
|
||||
|
||||
public const string ConcurrentDictionaryTypeName = "System.Collections.Concurrent.ConcurrentDictionary`2";
|
||||
|
||||
private static readonly ThreadSafeStore<Type, Func<object[], object>> CreatorCache =
|
||||
new ThreadSafeStore<Type, Func<object[], object>>(GetCreator);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user