-Fixed error when extension data bag doesn't inherit from Dictionary<TKey, TValue>

This commit is contained in:
James Newton-King
2014-11-03 13:29:57 -08:00
parent fbf24eed69
commit 3fa2949a38
4 changed files with 158 additions and 3 deletions
@@ -34,6 +34,7 @@
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Web.Extensions" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
+32 -1
View File
@@ -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<IList<PerformanceTests.RootObject>>(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<IList<PerformanceTests.RootObject>>(json);
}
sw.Stop();
Console.WriteLine("Finished. Total seconds: " + sw.Elapsed.TotalSeconds);
}
}
}
@@ -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<string, object>
{
private readonly IDictionary<string, object> _inner = new Dictionary<string, object>();
public void Add(string key, object value)
{
_inner.Add(key, value);
}
public bool ContainsKey(string key)
{
return _inner.ContainsKey(key);
}
public ICollection<string> 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<object> Values
{
get { return _inner.Values; }
}
public object this[string key]
{
get { return _inner[key]; }
set { _inner[key] = value; }
}
public void Add(KeyValuePair<string, object> item)
{
_inner.Add(item);
}
public void Clear()
{
_inner.Clear();
}
public bool Contains(KeyValuePair<string, object> item)
{
return _inner.Contains(item);
}
public void CopyTo(KeyValuePair<string, object>[] 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<string, object> item)
{
return _inner.Remove(item);
}
public IEnumerator<KeyValuePair<string, object>> 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<string, object> 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<Example>(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)
@@ -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<object, object> getExtensionDataDictionary = JsonTypeReflector.ReflectionDelegateFactory.CreateGet<object>(member);
Action<object, object> setExtensionDataDictionary = JsonTypeReflector.ReflectionDelegateFactory.CreateSet<object>(member);
Func<object> createExtensionDataDictionary = JsonTypeReflector.ReflectionDelegateFactory.CreateDefaultConstructor<object>(t);
Func<object> createExtensionDataDictionary = JsonTypeReflector.ReflectionDelegateFactory.CreateDefaultConstructor<object>(createdType);
MethodCall<object, object> setExtensionDataDictionaryValue = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall<object>(addMethod);
ExtensionDataSetter extensionDataSetter = (o, key, value) =>