-Changed serializer to create JObject/JArray when deserializing complex JSON to an object type

This commit is contained in:
JamesNK
2009-07-31 11:08:33 +00:00
parent 7f0bafeea7
commit 5611228772
6 changed files with 162 additions and 41 deletions
+41 -38
View File
@@ -1640,42 +1640,6 @@ keyword such as type of business.""
}
#endif
[Test]
public void PopulatePerson()
{
Person p = new Person();
JsonSerializer serializer = new JsonSerializer();
serializer.Populate(new StringReader(@"{""Name"":""James""}"), p);
Assert.AreEqual("James", p.Name);
}
[Test]
public void PopulateListOfPeople()
{
List<Person> p = new List<Person>();
JsonSerializer serializer = new JsonSerializer();
serializer.Populate(new StringReader(@"[{""Name"":""James""},{""Name"":""Jim""}]"), p);
Assert.AreEqual(2, p.Count);
Assert.AreEqual("James", p[0].Name);
Assert.AreEqual("Jim", p[1].Name);
}
[Test]
public void PopulateDictionary()
{
Dictionary<string, string> p = new Dictionary<string, string>();
JsonSerializer serializer = new JsonSerializer();
serializer.Populate(new StringReader(@"{""Name"":""James""}"), p);
Assert.AreEqual(1, p.Count);
Assert.AreEqual("James", p["Name"]);
}
public class DictionaryInterfaceClass
{
public string Name { get; set; }
@@ -1762,7 +1726,7 @@ keyword such as type of business.""
{
string json = @"/*comment*/ { /*comment*/
""Name"": /*comment*/ ""Apple"" /*comment*/, /*comment*/
""ExpiryDate"": ""\/Date(1230375600000+1300)\/"",
""ExpiryDate"": ""\/Date(1230422400000)\/"",
""Price"": 3.99,
""Sizes"": /*comment*/ [ /*comment*/
""Small"", /*comment*/
@@ -1774,7 +1738,7 @@ keyword such as type of business.""
Product deserializedProduct = (Product)JsonConvert.DeserializeObject(json, typeof(Product));
Assert.AreEqual("Apple", deserializedProduct.Name);
Assert.AreEqual(new DateTime(2008, 12, 28), deserializedProduct.ExpiryDate);
Assert.AreEqual(new DateTime(2008, 12, 28, 0, 0, 0, DateTimeKind.Utc), deserializedProduct.ExpiryDate);
Assert.AreEqual(3.99, deserializedProduct.Price);
Assert.AreEqual("Small", deserializedProduct.Sizes[0]);
Assert.AreEqual("Medium", deserializedProduct.Sizes[1]);
@@ -1935,5 +1899,44 @@ keyword such as type of business.""
Assert.AreEqual("Admin", r.RoleName);
Assert.AreEqual(RoleTransferDirection.First, r.Direction);
}
public class ObjectArrayPropertyTest
{
public string Action { get; set; }
public string Method { get; set; }
public object[] Data { get; set; }
}
[Test]
public void PrimitiveValuesInObjectArray()
{
string json = @"{""action"":""Router"",""method"":""Navigate"",""data"":[""dashboard"",null],""type"":""rpc"",""tid"":2}";
ObjectArrayPropertyTest o = JsonConvert.DeserializeObject<ObjectArrayPropertyTest>(json);
Assert.AreEqual("Router", o.Action);
Assert.AreEqual("Navigate", o.Method);
Assert.AreEqual(2, o.Data.Length);
Assert.AreEqual("dashboard", o.Data[0]);
Assert.AreEqual(null, o.Data[1]);
}
[Test]
public void ComplexValuesInObjectArray()
{
string json = @"{""action"":""Router"",""method"":""Navigate"",""data"":[""dashboard"",[""id"", 1, ""teststring"", ""test""],{""one"":1}],""type"":""rpc"",""tid"":2}";
ObjectArrayPropertyTest o = JsonConvert.DeserializeObject<ObjectArrayPropertyTest>(json);
Assert.AreEqual("Router", o.Action);
Assert.AreEqual("Navigate", o.Method);
Assert.AreEqual(3, o.Data.Length);
Assert.AreEqual("dashboard", o.Data[0]);
Assert.IsInstanceOfType(typeof(JArray), o.Data[1]);
Assert.AreEqual(4, ((JArray)o.Data[1]).Count);
Assert.IsInstanceOfType(typeof(JObject), o.Data[2]);
Assert.AreEqual(1, ((JObject)o.Data[2]).Count);
Assert.AreEqual(1, (int)((JObject)o.Data[2])["one"]);
}
}
}
@@ -69,6 +69,7 @@
<Compile Include="Schema\JsonSchemaNodeTests.cs" />
<Compile Include="Serialization\CamelCasePropertyNamesContractResolverTests.cs" />
<Compile Include="Serialization\EntitiesSerializationTests.cs" />
<Compile Include="Serialization\PopulateTests.cs" />
<Compile Include="Serialization\PreserveReferencesHandlingTests.cs" />
<Compile Include="Serialization\SerializationEventAttributeTests.cs" />
<Compile Include="Serialization\TypeNameHandlingTests.cs" />
@@ -73,6 +73,7 @@
<Compile Include="Schema\JsonSchemaNodeTests.cs" />
<Compile Include="Serialization\CamelCasePropertyNamesContractResolverTests.cs" />
<Compile Include="Serialization\EntitiesSerializationTests.cs" />
<Compile Include="Serialization\PopulateTests.cs" />
<Compile Include="Serialization\PreserveReferencesHandlingTests.cs" />
<Compile Include="Serialization\SerializationEventAttributeTests.cs" />
<Compile Include="Serialization\TypeNameHandlingTests.cs" />
@@ -106,6 +106,7 @@
<Compile Include="LinqToSql\LinqToSqlClassesSerializationTests.cs" />
<Compile Include="LinqToSql\Person.cs" />
<Compile Include="Serialization\EntitiesSerializationTests.cs" />
<Compile Include="Serialization\PopulateTests.cs" />
<Compile Include="Serialization\SerializationEventAttributeTests.cs" />
<Compile Include="Schema\ExtensionsTests.cs" />
<Compile Include="Schema\JsonSchemaModelBuilderTests.cs" />
@@ -0,0 +1,110 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Newtonsoft.Json.Tests.TestObjects;
using NUnit.Framework;
namespace Newtonsoft.Json.Tests.Serialization
{
public class PopulateTests : TestFixtureBase
{
[Test]
public void PopulatePerson()
{
Person p = new Person();
JsonSerializer serializer = new JsonSerializer();
serializer.Populate(new StringReader(@"{""Name"":""James""}"), p);
Assert.AreEqual("James", p.Name);
}
[Test]
public void PopulateStore()
{
Store s = new Store();
s.Color = StoreColor.Red;
s.product = new List<Product>
{
new Product
{
ExpiryDate = new DateTime(2000, 12, 3, 0, 0, 0, DateTimeKind.Utc),
Name = "ProductName!",
Price = 9.9m
}
};
s.Width = 99.99d;
s.Mottos = new List<string> { "Can do!", "We deliver!" };
string json = @"{
""Color"": 2,
""Establised"": ""\/Date(1264122061000+0000)\/"",
""Width"": 99.99,
""Employees"": 999,
""RoomsPerFloor"": [
1,
2,
3,
4,
5,
6,
7,
8,
9
],
""Open"": false,
""Symbol"": ""@"",
""Mottos"": [
""Fail whale""
],
""Cost"": 100980.1,
""Escape"": ""\r\n\t\f\b?{\\r\\n\""'"",
""product"": [
{
""Name"": ""ProductName!"",
""ExpiryDate"": ""\/Date(975801600000)\/"",
""Price"": 9.9,
""Sizes"": null
}
]
}";
JsonSerializer serializer = new JsonSerializer();
serializer.ObjectCreationHandling = ObjectCreationHandling.Replace;
serializer.Populate(new StringReader(json), s);
Assert.AreEqual(1, s.Mottos.Count);
Assert.AreEqual("Fail whale", s.Mottos[0]);
Assert.AreEqual(1, s.product.Count);
//Assert.AreEqual("James", p.Name);
}
[Test]
public void PopulateListOfPeople()
{
List<Person> p = new List<Person>();
JsonSerializer serializer = new JsonSerializer();
serializer.Populate(new StringReader(@"[{""Name"":""James""},{""Name"":""Jim""}]"), p);
Assert.AreEqual(2, p.Count);
Assert.AreEqual("James", p[0].Name);
Assert.AreEqual("Jim", p[1].Name);
}
[Test]
public void PopulateDictionary()
{
Dictionary<string, string> p = new Dictionary<string, string>();
JsonSerializer serializer = new JsonSerializer();
serializer.Populate(new StringReader(@"{""Name"":""James""}"), p);
Assert.AreEqual(1, p.Count);
Assert.AreEqual("James", p["Name"]);
}
}
}
@@ -270,7 +270,7 @@ namespace Newtonsoft.Json.Serialization
&& reader.TokenType == JsonToken.PropertyName);
}
if (objectType == null)
if (!HasDefinedType(objectType))
return CreateJObject(reader);
JsonContract contract = _serializer.ContractResolver.ResolveContract(objectType);
@@ -306,7 +306,7 @@ namespace Newtonsoft.Json.Serialization
JsonArrayContract arrayContract = contract as JsonArrayContract;
if (arrayContract == null)
throw new JsonSerializationException("Expected a JsonObjectContract or JsonDictionaryContract for type '{0}', got '{1}'.".FormatWith(CultureInfo.InvariantCulture, objectType, contract.GetType()));
throw new JsonSerializationException("Expected a JsonArrayContract for type '{0}', got '{1}'.".FormatWith(CultureInfo.InvariantCulture, objectType, contract.GetType()));
return arrayContract;
}
@@ -320,7 +320,7 @@ namespace Newtonsoft.Json.Serialization
private object CreateList(JsonReader reader, Type objectType, object existingValue, string reference)
{
object value;
if (objectType != null)
if (HasDefinedType(objectType))
{
JsonArrayContract contract = GetArrayContract(objectType);
@@ -336,6 +336,11 @@ namespace Newtonsoft.Json.Serialization
return value;
}
private bool HasDefinedType(Type type)
{
return (type != null && type != typeof (object));
}
private object EnsureType(object value, Type targetType)
{
// do something about null value when the targetType is a valuetype?