From 561122877290a1754f0b94eaf07a36705a368be7 Mon Sep 17 00:00:00 2001 From: JamesNK Date: Fri, 31 Jul 2009 11:08:33 +0000 Subject: [PATCH] -Changed serializer to create JObject/JArray when deserializing complex JSON to an object type --- .../JsonSerializerTest.cs | 79 +++++++------ .../Newtonsoft.Json.Tests.Compact.csproj | 1 + .../Newtonsoft.Json.Tests.Silverlight.csproj | 1 + .../Newtonsoft.Json.Tests.csproj | 1 + .../Serialization/PopulateTests.cs | 110 ++++++++++++++++++ .../Serialization/JsonSerializerReader.cs | 11 +- 6 files changed, 162 insertions(+), 41 deletions(-) create mode 100644 Src/Newtonsoft.Json.Tests/Serialization/PopulateTests.cs diff --git a/Src/Newtonsoft.Json.Tests/JsonSerializerTest.cs b/Src/Newtonsoft.Json.Tests/JsonSerializerTest.cs index 890699c4..7424f73a 100644 --- a/Src/Newtonsoft.Json.Tests/JsonSerializerTest.cs +++ b/Src/Newtonsoft.Json.Tests/JsonSerializerTest.cs @@ -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 p = new List(); - - 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 p = new Dictionary(); - - 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(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(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"]); + } } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Compact.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Compact.csproj index f34c4f53..3df20233 100644 --- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Compact.csproj +++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Compact.csproj @@ -69,6 +69,7 @@ + diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Silverlight.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Silverlight.csproj index a20396dc..a6547f9c 100644 --- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Silverlight.csproj +++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Silverlight.csproj @@ -73,6 +73,7 @@ + diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj index 92a6fa2f..cd129eae 100644 --- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj +++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj @@ -106,6 +106,7 @@ + diff --git a/Src/Newtonsoft.Json.Tests/Serialization/PopulateTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/PopulateTests.cs new file mode 100644 index 00000000..ad616391 --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/Serialization/PopulateTests.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 + { + 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 { "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 p = new List(); + + 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 p = new Dictionary(); + + JsonSerializer serializer = new JsonSerializer(); + serializer.Populate(new StringReader(@"{""Name"":""James""}"), p); + + Assert.AreEqual(1, p.Count); + Assert.AreEqual("James", p["Name"]); + } + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerReader.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerReader.cs index 2007b9e3..0f7d2ad8 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonSerializerReader.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerReader.cs @@ -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?