-Fix to preserve collection type information in certain situations when serializing
-Add missing Newtonsoft.Json.WindowsPhone.sln file
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -77,19 +77,40 @@ namespace Newtonsoft.Json.Serialization
|
||||
|
||||
if (_genericCollectionDefinitionType != null)
|
||||
{
|
||||
if (_genericWrapperType == null)
|
||||
{
|
||||
_genericWrapperType = ReflectionUtils.MakeGenericType(typeof (CollectionWrapper<>), CollectionItemType);
|
||||
|
||||
ConstructorInfo genericWrapperConstructor = _genericWrapperType.GetConstructor(new[] {_genericCollectionDefinitionType});
|
||||
_genericWrapperCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall<object>(genericWrapperConstructor);
|
||||
}
|
||||
|
||||
EnsureGenericWrapperCreator();
|
||||
return (IWrappedCollection) _genericWrapperCreator(null, list);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new CollectionWrapper<object>((IList<object>)((IEnumerable)list).Cast<object>().ToList());
|
||||
IList values = ((IEnumerable) list).Cast<object>().ToList();
|
||||
|
||||
if (CollectionItemType != null)
|
||||
{
|
||||
Array array = Array.CreateInstance(CollectionItemType, values.Count);
|
||||
for (int i = 0; i < values.Count; i++)
|
||||
{
|
||||
array.SetValue(values[i], i);
|
||||
}
|
||||
|
||||
values = array;
|
||||
}
|
||||
|
||||
return new CollectionWrapper<object>(values);
|
||||
}
|
||||
}
|
||||
|
||||
private void EnsureGenericWrapperCreator()
|
||||
{
|
||||
if (_genericWrapperType == null)
|
||||
{
|
||||
_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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user