-Fixed deserializing classes derived from ConcurrentDictionary

-Updated to latest immutable collections
-Tests
This commit is contained in:
James Newton-King
2015-04-05 01:46:58 +13:00
parent 0552affb83
commit 629c32062e
10 changed files with 98 additions and 42 deletions
@@ -57,4 +57,4 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("7.0.0.0")]
[assembly: AssemblyFileVersion("7.0.1.18402")]
[assembly: AssemblyFileVersion("7.0.1.18405")]
@@ -78,9 +78,9 @@
<HintPath>..\packages\NUnit.2.6.2\lib\nunit.framework.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Collections.Immutable, Version=1.1.20.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Reference Include="System.Collections.Immutable, Version=1.1.33.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\System.Collections.Immutable.1.1.33-beta\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll</HintPath>
<HintPath>..\packages\System.Collections.Immutable.1.1.34-rc\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll</HintPath>
</Reference>
<Reference Include="System.ComponentModel.DataAnnotations">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
@@ -44,9 +44,9 @@
<HintPath>..\packages\NUnit.2.6.2\lib\nunit.framework.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Collections.Immutable, Version=1.1.33.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\System.Collections.Immutable.1.1.33-beta\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll</HintPath>
<Reference Include="System.Collections.Immutable, Version=1.1.34.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Collections.Immutable.1.1.34-rc\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Core" />
@@ -76,4 +76,4 @@ using System.Security;
// by using the '*' as shown below:
[assembly: AssemblyVersion("7.0.0.0")]
[assembly: AssemblyFileVersion("7.0.1.18402")]
[assembly: AssemblyFileVersion("7.0.1.18405")]
@@ -46,7 +46,6 @@ using Newtonsoft.Json.Linq;
namespace Newtonsoft.Json.Tests.Serialization
{
[TestFixture]
[Ignore]
public class ImmutableCollectionsTests : TestFixtureBase
{
#region List
@@ -441,5 +440,4 @@ namespace Newtonsoft.Json.Tests.Serialization
#endregion
}
}
#endif
@@ -26,6 +26,7 @@
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Runtime.Serialization;
#if !(NET35 || NET20 || PORTABLE || DNXCORE50 || PORTABLE40)
using System.Collections.Concurrent;
#endif
@@ -73,6 +74,57 @@ namespace Newtonsoft.Json.Tests.Serialization
}
#endif
#if !(NET35 || NET20 || PORTABLE || PORTABLE40)
public class SomeObject
{
public string Text1 { get; set; }
}
public class CustomConcurrentDictionary : ConcurrentDictionary<string, List<SomeObject>>
{
[OnDeserialized]
internal void OnDeserializedMethod(StreamingContext context)
{
((IDictionary)this).Add("key2", new List<SomeObject>
{
new SomeObject
{
Text1 = "value2"
}
});
}
}
[Test]
public void SerializeCustomConcurrentDictionary()
{
IDictionary d = new CustomConcurrentDictionary();
d.Add("key", new List<SomeObject>
{
new SomeObject
{
Text1 = "value1"
}
});
string json = JsonConvert.SerializeObject(d, Formatting.Indented);
Assert.AreEqual(@"{
""key"": [
{
""Text1"": ""value1""
}
]
}", json);
CustomConcurrentDictionary d2 = JsonConvert.DeserializeObject<CustomConcurrentDictionary>(json);
Assert.AreEqual(2, d2.Count);
Assert.AreEqual("value1", d2["key"][0].Text1);
Assert.AreEqual("value2", d2["key2"][0].Text1);
}
#endif
[Test]
public void MultiDObjectArray()
{
+1 -1
View File
@@ -3,5 +3,5 @@
<package id="Autofac" version="3.5.0" targetFramework="net45" />
<package id="FSharp.Core" version="4.0.0" targetFramework="net45" />
<package id="NUnit" version="2.6.2" targetFramework="net45" />
<package id="System.Collections.Immutable" version="1.1.33-beta" targetFramework="net45" />
<package id="System.Collections.Immutable" version="1.1.34-rc" targetFramework="net45" />
</packages>
+1
View File
@@ -2,4 +2,5 @@
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_FIELD_ATTRIBUTE_ON_SAME_LINE/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_AROUND_MULTIPLICATIVE_OP/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LINES/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
</wpf:ResourceDictionary>
@@ -92,5 +92,5 @@ using System.Security;
// by using the '*' as shown below:
[assembly: AssemblyVersion("7.0.0.0")]
[assembly: AssemblyFileVersion("7.0.1.18402")]
[assembly: AssemblyFileVersion("7.0.1.18405")]
[assembly: CLSCompliant(true)]
@@ -744,43 +744,16 @@ namespace Newtonsoft.Json.Serialization
GetCallbackMethodsForType(t, out onSerializing, out onSerialized, out onDeserializing, out onDeserialized, out onError);
if (onSerializing != null)
{
#if !(NET35 || NET20 || NETFX_CORE)
if (t.Name != FSharpUtils.FSharpSetTypeName && t.Name != FSharpUtils.FSharpMapTypeName)
#endif
{
#if NETFX_CORE
if (!t.IsGenericType() || (t.GetGenericTypeDefinition() != typeof(ConcurrentDictionary<,>)))
contract.OnSerializingCallbacks.AddRange(onSerializing);
#else
contract.OnSerializingCallbacks.AddRange(onSerializing);
#endif
}
}
contract.OnSerializingCallbacks.AddRange(onSerializing);
if (onSerialized != null)
contract.OnSerializedCallbacks.AddRange(onSerialized);
if (onDeserializing != null)
{
contract.OnDeserializingCallbacks.AddRange(onDeserializing);
}
if (onDeserialized != null)
{
#if !(NET35 || NET20 || NETFX_CORE)
if (t.Name != FSharpUtils.FSharpSetTypeName && t.Name != FSharpUtils.FSharpMapTypeName)
#endif
{
// ConcurrentDictionary throws an error here so don't use its OnDeserialized - http://json.codeplex.com/discussions/257093
#if !(NET35 || NET20 || PORTABLE || PORTABLE40)
if (!t.IsGenericType() || (t.GetGenericTypeDefinition() != typeof(ConcurrentDictionary<,>)))
contract.OnDeserializedCallbacks.AddRange(onDeserialized);
#else
contract.OnDeserializedCallbacks.AddRange(onDeserialized);
#endif
}
}
contract.OnDeserializedCallbacks.AddRange(onDeserialized);
if (onError != null)
contract.OnErrorCallbacks.AddRange(onError);
@@ -803,6 +776,9 @@ namespace Newtonsoft.Json.Serialization
MethodInfo currentOnDeserialized = null;
MethodInfo currentOnError = null;
bool skipSerializing = ShouldSkipSerializing(baseType);
bool skipDeserialized = ShouldSkipDeserialized(baseType);
foreach (MethodInfo method in baseType.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly))
{
// compact framework errors when getting parameters for a generic method
@@ -813,7 +789,7 @@ namespace Newtonsoft.Json.Serialization
Type prevAttributeType = null;
ParameterInfo[] parameters = method.GetParameters();
if (IsValidCallback(method, parameters, typeof(OnSerializingAttribute), currentOnSerializing, ref prevAttributeType))
if (!skipSerializing && IsValidCallback(method, parameters, typeof(OnSerializingAttribute), currentOnSerializing, ref prevAttributeType))
{
onSerializing = onSerializing ?? new List<SerializationCallback>();
onSerializing.Add(JsonContract.CreateSerializationCallback(method));
@@ -831,7 +807,7 @@ namespace Newtonsoft.Json.Serialization
onDeserializing.Add(JsonContract.CreateSerializationCallback(method));
currentOnDeserializing = method;
}
if (IsValidCallback(method, parameters, typeof(OnDeserializedAttribute), currentOnDeserialized, ref prevAttributeType))
if (!skipDeserialized && IsValidCallback(method, parameters, typeof(OnDeserializedAttribute), currentOnDeserialized, ref prevAttributeType))
{
onDeserialized = onDeserialized ?? new List<SerializationCallback>();
onDeserialized.Add(JsonContract.CreateSerializationCallback(method));
@@ -847,6 +823,35 @@ namespace Newtonsoft.Json.Serialization
}
}
private static bool ShouldSkipDeserialized(Type t)
{
#if !(NET35 || NET20 || PORTABLE || PORTABLE40)
// ConcurrentDictionary throws an error in its OnDeserialized so ignore - http://json.codeplex.com/discussions/257093
if (t.IsGenericType() && t.GetGenericTypeDefinition() == typeof(ConcurrentDictionary<,>))
return true;
#endif
#if !(NET35 || NET20 || NETFX_CORE)
if (t.Name == FSharpUtils.FSharpSetTypeName || t.Name == FSharpUtils.FSharpMapTypeName)
return true;
#endif
return false;
}
private static bool ShouldSkipSerializing(Type t)
{
#if !(NET35 || NET20 || NETFX_CORE)
if (t.Name == FSharpUtils.FSharpSetTypeName || t.Name == FSharpUtils.FSharpMapTypeName)
return true;
#endif
#if NETFX_CORE
if (t.IsGenericType() && t.GetGenericTypeDefinition() == typeof(ConcurrentDictionary<,>))
return true;
#endif
return false;
}
private List<Type> GetClassHierarchyForType(Type type)
{
List<Type> ret = new List<Type>();