diff --git a/Src/Newtonsoft.Json.TestConsole/Newtonsoft.Json.TestConsole.csproj b/Src/Newtonsoft.Json.TestConsole/Newtonsoft.Json.TestConsole.csproj index f1f493da..b5f3f346 100644 --- a/Src/Newtonsoft.Json.TestConsole/Newtonsoft.Json.TestConsole.csproj +++ b/Src/Newtonsoft.Json.TestConsole/Newtonsoft.Json.TestConsole.csproj @@ -34,6 +34,7 @@ + diff --git a/Src/Newtonsoft.Json.TestConsole/Program.cs b/Src/Newtonsoft.Json.TestConsole/Program.cs index 708254fd..42e3546f 100644 --- a/Src/Newtonsoft.Json.TestConsole/Program.cs +++ b/Src/Newtonsoft.Json.TestConsole/Program.cs @@ -5,6 +5,7 @@ using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Web.Script.Serialization; using Newtonsoft.Json.Tests; namespace Newtonsoft.Json.TestConsole @@ -28,6 +29,7 @@ namespace Newtonsoft.Json.TestConsole //WriteLargeJson(); //DeserializeJson(); ReadLargeJson(); + //ReadLargeJsonJavaScriptSerializer(); Console.WriteLine(); Console.WriteLine("Finished"); @@ -92,7 +94,7 @@ namespace Newtonsoft.Json.TestConsole Stopwatch sw = new Stopwatch(); sw.Start(); - for (int i = 0; i < 10; i++) + for (int i = 0; i < 5; i++) { using (var jsonFile = System.IO.File.OpenText("large.json")) using (JsonTextReader jsonTextReader = new JsonTextReader(jsonFile)) @@ -106,5 +108,34 @@ namespace Newtonsoft.Json.TestConsole Console.WriteLine("Finished. Total seconds: " + sw.Elapsed.TotalSeconds); } + + public static void ReadLargeJsonJavaScriptSerializer() + { + string json = System.IO.File.ReadAllText("large.json"); + + JavaScriptSerializer s = new JavaScriptSerializer(); + s.MaxJsonLength = int.MaxValue; + s.Deserialize>(json); + + Console.WriteLine("Press any key to start deserialization"); + Console.ReadKey(); + Console.WriteLine("Deserializing..."); + + Stopwatch sw = new Stopwatch(); + sw.Start(); + + for (int i = 0; i < 5; i++) + { + json = System.IO.File.ReadAllText("large.json"); + + s = new JavaScriptSerializer(); + s.MaxJsonLength = int.MaxValue; + s.Deserialize>(json); + } + + sw.Stop(); + + Console.WriteLine("Finished. Total seconds: " + sw.Elapsed.TotalSeconds); + } } } diff --git a/Src/Newtonsoft.Json.Tests/Serialization/ExtensionDataTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/ExtensionDataTests.cs index 5f8fbb04..07f76e5e 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/ExtensionDataTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/ExtensionDataTests.cs @@ -25,6 +25,7 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Text; using Newtonsoft.Json.Linq; using Newtonsoft.Json.Tests.TestObjects; @@ -45,6 +46,124 @@ namespace Newtonsoft.Json.Tests.Serialization [TestFixture] public class ExtensionDataTests : TestFixtureBase { + public class CustomDictionary : IDictionary + { + private readonly IDictionary _inner = new Dictionary(); + + public void Add(string key, object value) + { + _inner.Add(key, value); + } + + public bool ContainsKey(string key) + { + return _inner.ContainsKey(key); + } + + public ICollection Keys + { + get { return _inner.Keys; } + } + + public bool Remove(string key) + { + return _inner.Remove(key); + } + + public bool TryGetValue(string key, out object value) + { + return _inner.TryGetValue(key, out value); + } + + public ICollection Values + { + get { return _inner.Values; } + } + + public object this[string key] + { + get { return _inner[key]; } + set { _inner[key] = value; } + } + + public void Add(KeyValuePair item) + { + _inner.Add(item); + } + + public void Clear() + { + _inner.Clear(); + } + + public bool Contains(KeyValuePair item) + { + return _inner.Contains(item); + } + + public void CopyTo(KeyValuePair[] array, int arrayIndex) + { + _inner.CopyTo(array, arrayIndex); + } + + public int Count + { + get { return _inner.Count; } + } + + public bool IsReadOnly + { + get { return _inner.IsReadOnly; } + } + + public bool Remove(KeyValuePair item) + { + return _inner.Remove(item); + } + + public IEnumerator> GetEnumerator() + { + return _inner.GetEnumerator(); + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() + { + return _inner.GetEnumerator(); + } + } + + public class Example + { + public Example() + { + Data = new CustomDictionary(); + } + + [JsonExtensionData] + public IDictionary Data { get; private set; } + } + + [Test] + public void Sdfsdf() + { + Example e = new Example(); + e.Data.Add("extensionData1", new int[] { 1, 2, 3 }); + + string json = JsonConvert.SerializeObject(e, Formatting.Indented); + + Console.WriteLine(json); + + Example e2 = JsonConvert.DeserializeObject(json); + + JToken o1 = (JToken)e2.Data["extensionData1"]; + + Assert.AreEqual(JTokenType.Array, o1.Type); + Assert.AreEqual(3, o1.Count()); + Assert.AreEqual(1, (int)o1[0]); + Assert.AreEqual(2, (int)o1[1]); + Assert.AreEqual(3, (int)o1[2]); + } + public class ExtensionDataDeserializeWithNonDefaultConstructor { public ExtensionDataDeserializeWithNonDefaultConstructor(string name) diff --git a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs index 5e3b20e2..f9a4433c 100644 --- a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs +++ b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs @@ -469,14 +469,18 @@ namespace Newtonsoft.Json.Serialization Type valueType = dictionaryType.GetGenericArguments()[1]; bool isJTokenValueType = typeof(JToken).IsAssignableFrom(valueType); + Type createdType; + // change type to a class if it is the base interface so it can be instantiated if needed if (ReflectionUtils.IsGenericDefinition(t, typeof(IDictionary<,>))) - t = typeof(Dictionary<,>).MakeGenericType(keyType, valueType); + createdType = typeof(Dictionary<,>).MakeGenericType(keyType, valueType); + else + createdType = t; MethodInfo addMethod = t.GetMethod("Add", new[] { keyType, valueType }); Func getExtensionDataDictionary = JsonTypeReflector.ReflectionDelegateFactory.CreateGet(member); Action setExtensionDataDictionary = JsonTypeReflector.ReflectionDelegateFactory.CreateSet(member); - Func createExtensionDataDictionary = JsonTypeReflector.ReflectionDelegateFactory.CreateDefaultConstructor(t); + Func createExtensionDataDictionary = JsonTypeReflector.ReflectionDelegateFactory.CreateDefaultConstructor(createdType); MethodCall setExtensionDataDictionaryValue = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(addMethod); ExtensionDataSetter extensionDataSetter = (o, key, value) =>