-Fixed error when deserializing null value into ConcurrentDictionary

This commit is contained in:
James Newton-King
2018-01-20 17:23:38 +13:00
parent e1dfefe00b
commit 8ece2b31b9
4 changed files with 33 additions and 2 deletions
@@ -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);