diff --git a/Src/Newtonsoft.Json.TestConsole/Properties/AssemblyInfo.cs b/Src/Newtonsoft.Json.TestConsole/Properties/AssemblyInfo.cs index 9c9dcc51..c14ae0b5 100644 --- a/Src/Newtonsoft.Json.TestConsole/Properties/AssemblyInfo.cs +++ b/Src/Newtonsoft.Json.TestConsole/Properties/AssemblyInfo.cs @@ -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")] diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Portable.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Portable.csproj index 0ab0e85e..68cb85a7 100644 --- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Portable.csproj +++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Portable.csproj @@ -78,9 +78,9 @@ ..\packages\NUnit.2.6.2\lib\nunit.framework.dll - + False - ..\packages\System.Collections.Immutable.1.1.33-beta\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll + ..\packages\System.Collections.Immutable.1.1.34-rc\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll 3.5 diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj index 0ed270aa..db81190e 100644 --- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj +++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj @@ -44,9 +44,9 @@ ..\packages\NUnit.2.6.2\lib\nunit.framework.dll - - False - ..\packages\System.Collections.Immutable.1.1.33-beta\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll + + ..\packages\System.Collections.Immutable.1.1.34-rc\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll + True diff --git a/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs b/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs index a2c90e25..18e37bfd 100644 --- a/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs +++ b/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs @@ -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")] diff --git a/Src/Newtonsoft.Json.Tests/Serialization/ImmutableCollectionsTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/ImmutableCollectionsTests.cs index 5a6a0d3b..b4293240 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/ImmutableCollectionsTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/ImmutableCollectionsTests.cs @@ -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 \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerCollectionsTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerCollectionsTests.cs index 8aa483c3..b5223cd5 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerCollectionsTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerCollectionsTests.cs @@ -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> + { + [OnDeserialized] + internal void OnDeserializedMethod(StreamingContext context) + { + ((IDictionary)this).Add("key2", new List + { + new SomeObject + { + Text1 = "value2" + } + }); + } + } + + [Test] + public void SerializeCustomConcurrentDictionary() + { + IDictionary d = new CustomConcurrentDictionary(); + d.Add("key", new List + { + new SomeObject + { + Text1 = "value1" + } + }); + + string json = JsonConvert.SerializeObject(d, Formatting.Indented); + + Assert.AreEqual(@"{ + ""key"": [ + { + ""Text1"": ""value1"" + } + ] +}", json); + + CustomConcurrentDictionary d2 = JsonConvert.DeserializeObject(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() { diff --git a/Src/Newtonsoft.Json.Tests/packages.config b/Src/Newtonsoft.Json.Tests/packages.config index edf38072..591f8cec 100644 --- a/Src/Newtonsoft.Json.Tests/packages.config +++ b/Src/Newtonsoft.Json.Tests/packages.config @@ -3,5 +3,5 @@ - + \ No newline at end of file diff --git a/Src/Newtonsoft.Json.sln.DotSettings b/Src/Newtonsoft.Json.sln.DotSettings index 6a89a056..c97ec47f 100644 --- a/Src/Newtonsoft.Json.sln.DotSettings +++ b/Src/Newtonsoft.Json.sln.DotSettings @@ -2,4 +2,5 @@ False True False + True \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs b/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs index fdd58ec9..614dddda 100644 --- a/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs +++ b/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs @@ -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)] diff --git a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs index 5ca78eb1..6bc471db 100644 --- a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs +++ b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs @@ -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(); 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(); 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 GetClassHierarchyForType(Type type) { List ret = new List();