From 695742563b09ac2c11df30f60cf8899ee9a2ddf1 Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Sat, 30 Aug 2014 14:34:16 +1200 Subject: [PATCH] -Fixed Win8 build -Fixed serializing ObservableCollection on Win8 --- Src/Newtonsoft.Json.Tests/Linq/JValueTests.cs | 4 ++-- .../Serialization/JsonSerializerTest.cs | 11 ++++++++++ .../Serialization/JsonArrayContract.cs | 8 +++---- .../Serialization/JsonDictionaryContract.cs | 2 +- .../Utilities/CollectionUtils.cs | 21 ++++++++++++++++--- 5 files changed, 36 insertions(+), 10 deletions(-) diff --git a/Src/Newtonsoft.Json.Tests/Linq/JValueTests.cs b/Src/Newtonsoft.Json.Tests/Linq/JValueTests.cs index 4d13e910..83034882 100644 --- a/Src/Newtonsoft.Json.Tests/Linq/JValueTests.cs +++ b/Src/Newtonsoft.Json.Tests/Linq/JValueTests.cs @@ -791,10 +791,10 @@ namespace Newtonsoft.Json.Tests.Linq StringComparison e5 = v.ToObject(); Assert.AreEqual(StringComparison.Ordinal, e5); - v = new JValue((int)StringComparison.InvariantCultureIgnoreCase); + v = new JValue((int)StringComparison.OrdinalIgnoreCase); Assert.AreEqual(JTokenType.Integer, v.Type); StringComparison e6 = v.ToObject(); - Assert.AreEqual(StringComparison.InvariantCultureIgnoreCase, e6); + Assert.AreEqual(StringComparison.OrdinalIgnoreCase, e6); } #endif } diff --git a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs index a8134a7b..35d72cf7 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs @@ -127,6 +127,17 @@ namespace Newtonsoft.Json.Tests.Serialization } #endif +#if !NET20 + [Test] + public void DeserializeObservableCollection() + { + ObservableCollection s = JsonConvert.DeserializeObject>("['1','2']"); + Assert.AreEqual(2, s.Count); + Assert.AreEqual("1", s[0]); + Assert.AreEqual("2", s[1]); + } +#endif + #if !NET20 [Test] public void PopulateResetSettings() diff --git a/Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs b/Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs index 6f6bf84a..fe4c40b0 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs @@ -101,7 +101,7 @@ namespace Newtonsoft.Json.Serialization CreatedType = typeof(List); if (CollectionItemType != null) - ParametrizedCreator = CollectionUtils.ResolveEnumableCollectionConstructor(underlyingType, CollectionItemType); + ParametrizedCreator = CollectionUtils.ResolveEnumerableCollectionConstructor(underlyingType, CollectionItemType); IsReadOnlyOrFixedSize = ReflectionUtils.InheritsGenericDefinition(underlyingType, typeof(ReadOnlyCollection<>)); canDeserialize = true; @@ -119,7 +119,7 @@ namespace Newtonsoft.Json.Serialization CreatedType = typeof(HashSet<>).MakeGenericType(CollectionItemType); #endif - ParametrizedCreator = CollectionUtils.ResolveEnumableCollectionConstructor(underlyingType, CollectionItemType); + ParametrizedCreator = CollectionUtils.ResolveEnumerableCollectionConstructor(underlyingType, CollectionItemType); canDeserialize = true; ShouldCreateWrapper = true; } @@ -133,7 +133,7 @@ namespace Newtonsoft.Json.Serialization CreatedType = typeof(ReadOnlyCollection<>).MakeGenericType(CollectionItemType); _genericCollectionDefinitionType = typeof(List<>).MakeGenericType(CollectionItemType); - ParametrizedCreator = CollectionUtils.ResolveEnumableCollectionConstructor(CreatedType, CollectionItemType); + ParametrizedCreator = CollectionUtils.ResolveEnumerableCollectionConstructor(CreatedType, CollectionItemType); IsReadOnlyOrFixedSize = true; canDeserialize = (ParametrizedCreator != null); } @@ -145,7 +145,7 @@ namespace Newtonsoft.Json.Serialization if (ReflectionUtils.IsGenericDefinition(UnderlyingType, typeof(IEnumerable<>))) CreatedType = typeof(List<>).MakeGenericType(CollectionItemType); - ParametrizedCreator = CollectionUtils.ResolveEnumableCollectionConstructor(underlyingType, CollectionItemType); + ParametrizedCreator = CollectionUtils.ResolveEnumerableCollectionConstructor(underlyingType, CollectionItemType); #if !(NET35 || NET20 || NETFX_CORE) if (ParametrizedCreator == null && underlyingType.Name == FSharpUtils.FSharpListTypeName) diff --git a/Src/Newtonsoft.Json/Serialization/JsonDictionaryContract.cs b/Src/Newtonsoft.Json/Serialization/JsonDictionaryContract.cs index fe06df80..25759258 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonDictionaryContract.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonDictionaryContract.cs @@ -117,7 +117,7 @@ namespace Newtonsoft.Json.Serialization if (keyType != null && valueType != null) { - ParametrizedCreator = CollectionUtils.ResolveEnumableCollectionConstructor(CreatedType, typeof(KeyValuePair<,>).MakeGenericType(keyType, valueType)); + ParametrizedCreator = CollectionUtils.ResolveEnumerableCollectionConstructor(CreatedType, typeof(KeyValuePair<,>).MakeGenericType(keyType, valueType)); #if !(NET35 || NET20 || NETFX_CORE) if (ParametrizedCreator == null && underlyingType.Name == FSharpUtils.FSharpMapTypeName) diff --git a/Src/Newtonsoft.Json/Utilities/CollectionUtils.cs b/Src/Newtonsoft.Json/Utilities/CollectionUtils.cs index 18e6f7c5..2230e4db 100644 --- a/Src/Newtonsoft.Json/Utilities/CollectionUtils.cs +++ b/Src/Newtonsoft.Json/Utilities/CollectionUtils.cs @@ -102,9 +102,10 @@ namespace Newtonsoft.Json.Utilities return false; } - public static ObjectConstructor ResolveEnumableCollectionConstructor(Type collectionType, Type collectionItemType) + public static ObjectConstructor ResolveEnumerableCollectionConstructor(Type collectionType, Type collectionItemType) { Type genericEnumerable = typeof(IEnumerable<>).MakeGenericType(collectionItemType); + ConstructorInfo match = null; foreach (ConstructorInfo constructor in collectionType.GetConstructors(BindingFlags.Public | BindingFlags.Instance)) { @@ -112,11 +113,25 @@ namespace Newtonsoft.Json.Utilities if (parameters.Count == 1) { - if (genericEnumerable.IsAssignableFrom(parameters[0].ParameterType)) - return JsonTypeReflector.ReflectionDelegateFactory.CreateParametrizedConstructor(constructor); + if (genericEnumerable == parameters[0].ParameterType) + { + // exact match + match = constructor; + break; + } + + // incase we can't find an exact match, use first inexact + if (match == null) + { + if (genericEnumerable.IsAssignableFrom(parameters[0].ParameterType)) + match = constructor; + } } } + if (match != null) + return JsonTypeReflector.ReflectionDelegateFactory.CreateParametrizedConstructor(match); + return null; }