diff options
author | JamesNK <james@newtonking.com> | 2010-11-17 10:31:20 +0300 |
---|---|---|
committer | JamesNK <james@newtonking.com> | 2010-11-17 10:31:20 +0300 |
commit | 5c0431464be353671d2c3b9607018fbf34045657 (patch) | |
tree | bc8296bbc496f6c98800536ceb471551e302b994 | |
parent | 15ea91fb63f40e7ea0a1dfb1057b949d424bb63c (diff) |
-Fix to preserve collection type information in certain situations when serializing
-Add missing Newtonsoft.Json.WindowsPhone.sln file
-rw-r--r-- | Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs | 64 | ||||
-rw-r--r-- | Src/Newtonsoft.Json.WindowsPhone.sln | 31 | ||||
-rw-r--r-- | Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs | 35 |
3 files changed, 120 insertions, 10 deletions
diff --git a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs index 5ece94d..cc80491 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs @@ -3795,11 +3795,11 @@ keyword such as type of business."" public void DeserializeNullableStruct()
{
NullableStructPropertyClass nullableStructPropertyClass = new NullableStructPropertyClass();
- nullableStructPropertyClass.Foo1 = new StructISerializable() {Name = "foo 1"};
- nullableStructPropertyClass.Foo2 = new StructISerializable() {Name = "foo 2"};
+ nullableStructPropertyClass.Foo1 = new StructISerializable() { Name = "foo 1" };
+ nullableStructPropertyClass.Foo2 = new StructISerializable() { Name = "foo 2" };
NullableStructPropertyClass barWithNull = new NullableStructPropertyClass();
- barWithNull.Foo1 = new StructISerializable() {Name = "foo 1"};
+ barWithNull.Foo1 = new StructISerializable() { Name = "foo 1" };
barWithNull.Foo2 = null;
//throws error on deserialization because bar1.Foo2 is of type Foo?
@@ -3827,5 +3827,63 @@ keyword such as type of business."" });
}
#endif
+
+ [Test]
+ public void SerializingIEnumerableOfTShouldRetainGenericTypeInfo()
+ {
+ CustomEnumerable<Product> products = new CustomEnumerable<Product>();
+
+ string json = JsonConvert.SerializeObject(products, Formatting.Indented, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All });
+
+ Assert.AreEqual(@"{
+ ""$type"": ""Newtonsoft.Json.Tests.TestObjects.Product[], Newtonsoft.Json.Tests"",
+ ""$values"": []
+}", json);
+ }
+
+ public class CustomEnumerable<T> : IEnumerable<T>
+ {
+ //NOTE: a simple linked list
+ private readonly T value;
+ private readonly CustomEnumerable<T> next;
+ private readonly int count;
+
+ private CustomEnumerable(T value, CustomEnumerable<T> next)
+ {
+ this.value = value;
+ this.next = next;
+ count = this.next.count + 1;
+ }
+
+ public CustomEnumerable()
+ {
+ count = 0;
+ }
+
+ public CustomEnumerable<T> AddFirst(T newVal)
+ {
+ return new CustomEnumerable<T>(newVal, this);
+ }
+
+ public IEnumerator<T> GetEnumerator()
+ {
+ if (count == 0) // last node
+ yield break;
+ yield return value;
+
+ var nextInLine = next;
+ while (nextInLine != null)
+ {
+ if (nextInLine.count != 0)
+ yield return nextInLine.value;
+ nextInLine = nextInLine.next;
+ }
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+ }
}
}
\ No newline at end of file diff --git a/Src/Newtonsoft.Json.WindowsPhone.sln b/Src/Newtonsoft.Json.WindowsPhone.sln new file mode 100644 index 0000000..dfc12d9 --- /dev/null +++ b/Src/Newtonsoft.Json.WindowsPhone.sln @@ -0,0 +1,31 @@ +
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Lib", "Lib", "{F69285DD-24FB-4A60-AE8B-4C2744285D0F}"
+ ProjectSection(SolutionItems) = preProject
+ Lib\NUnit\Silverlight\nunit.framework.dll = Lib\NUnit\Silverlight\nunit.framework.dll
+ EndProjectSection
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Newtonsoft.Json.WindowsPhone", "Newtonsoft.Json\Newtonsoft.Json.WindowsPhone.csproj", "{7A7F70AB-5C07-47ED-BDD2-ECC14DBACA5E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Newtonsoft.Json.Tests.WindowsPhone", "Newtonsoft.Json.Tests\Newtonsoft.Json.Tests.WindowsPhone.csproj", "{5ED71C8C-D0A6-487C-9A8C-BB855ECEAF75}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {7A7F70AB-5C07-47ED-BDD2-ECC14DBACA5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7A7F70AB-5C07-47ED-BDD2-ECC14DBACA5E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7A7F70AB-5C07-47ED-BDD2-ECC14DBACA5E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7A7F70AB-5C07-47ED-BDD2-ECC14DBACA5E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5ED71C8C-D0A6-487C-9A8C-BB855ECEAF75}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5ED71C8C-D0A6-487C-9A8C-BB855ECEAF75}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5ED71C8C-D0A6-487C-9A8C-BB855ECEAF75}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5ED71C8C-D0A6-487C-9A8C-BB855ECEAF75}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs b/Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs index 8137531..01aede8 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs @@ -77,19 +77,40 @@ namespace Newtonsoft.Json.Serialization if (_genericCollectionDefinitionType != null)
{
- if (_genericWrapperType == null)
+ EnsureGenericWrapperCreator();
+ return (IWrappedCollection) _genericWrapperCreator(null, list);
+ }
+ else
+ {
+ IList values = ((IEnumerable) list).Cast<object>().ToList();
+
+ if (CollectionItemType != null)
{
- _genericWrapperType = ReflectionUtils.MakeGenericType(typeof (CollectionWrapper<>), CollectionItemType);
+ Array array = Array.CreateInstance(CollectionItemType, values.Count);
+ for (int i = 0; i < values.Count; i++)
+ {
+ array.SetValue(values[i], i);
+ }
- ConstructorInfo genericWrapperConstructor = _genericWrapperType.GetConstructor(new[] {_genericCollectionDefinitionType});
- _genericWrapperCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall<object>(genericWrapperConstructor);
+ values = array;
}
- return (IWrappedCollection) _genericWrapperCreator(null, list);
+ return new CollectionWrapper<object>(values);
}
- else
+ }
+
+ private void EnsureGenericWrapperCreator()
+ {
+ if (_genericWrapperType == null)
{
- return new CollectionWrapper<object>((IList<object>)((IEnumerable)list).Cast<object>().ToList());
+ _genericWrapperType = ReflectionUtils.MakeGenericType(typeof (CollectionWrapper<>), CollectionItemType);
+
+ Type constructorArgument = (ReflectionUtils.InheritsGenericDefinition(_genericCollectionDefinitionType, typeof (List<>)))
+ ? ReflectionUtils.MakeGenericType(typeof (ICollection<>), CollectionItemType)
+ : _genericCollectionDefinitionType;
+
+ ConstructorInfo genericWrapperConstructor = _genericWrapperType.GetConstructor(new[] { constructorArgument });
+ _genericWrapperCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall<object>(genericWrapperConstructor);
}
}
|