diff options
author | JamesNK <james@newtonking.com> | 2011-01-08 07:39:33 +0300 |
---|---|---|
committer | JamesNK <james@newtonking.com> | 2011-01-08 07:39:33 +0300 |
commit | ac6c65f48aa4833eac0626acf93f740f6d00a9b6 (patch) | |
tree | af13caddd6d7c03e6c6be39360f9c045795f6f3b /Src | |
parent | 0fb78fdb91674547e582115125ff4096b8de463c (diff) |
-Updated nuspec file for 4.0
-Added Load and Parse helper methods to JToken
-Fixed performance issues when deserializing with partial type names
-Fixed deserializing certain decimal values on classes with non-default constructors
Diffstat (limited to 'Src')
-rw-r--r-- | Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs | 32 | ||||
-rw-r--r-- | Src/Newtonsoft.Json.Tests/Linq/JTokenTests.cs | 16 | ||||
-rw-r--r-- | Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs | 28 | ||||
-rw-r--r-- | Src/Newtonsoft.Json/Linq/JArray.cs | 4 | ||||
-rw-r--r-- | Src/Newtonsoft.Json/Linq/JConstructor.cs | 2 | ||||
-rw-r--r-- | Src/Newtonsoft.Json/Linq/JObject.cs | 4 | ||||
-rw-r--r-- | Src/Newtonsoft.Json/Linq/JProperty.cs | 2 | ||||
-rw-r--r-- | Src/Newtonsoft.Json/Linq/JToken.cs | 26 | ||||
-rw-r--r-- | Src/Newtonsoft.Json/Serialization/DefaultSerializationBinder.cs | 58 | ||||
-rw-r--r-- | Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs | 8 |
10 files changed, 157 insertions, 23 deletions
diff --git a/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs b/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs index 6a57fa6..f80566f 100644 --- a/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs +++ b/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs @@ -203,7 +203,7 @@ Parameter name: reader")] {
new JsonTextReader(null);
}
-
+
[Test]
[ExpectedException(typeof(JsonReaderException), ExpectedMessage = "Unterminated string. Expected delimiter: '. Line 1, position 3.")]
public void UnexpectedEndOfString()
@@ -220,7 +220,7 @@ Parameter name: reader")] Assert.AreEqual("h\0i", reader.Value);
}
-
+
[Test]
[ExpectedException(typeof(JsonReaderException), ExpectedMessage = "Unexpected end while parsing unicode character. Line 1, position 7.")]
public void UnexpectedEndOfHex()
@@ -228,7 +228,7 @@ Parameter name: reader")] JsonReader reader = new JsonTextReader(new StringReader(@"'h\u006"));
reader.Read();
}
-
+
[Test]
[ExpectedException(typeof(JsonReaderException), ExpectedMessage = "Unterminated string. Expected delimiter: '. Line 1, position 3.")]
public void UnexpectedEndOfControlCharacter()
@@ -494,10 +494,10 @@ bye", reader.Value); string json = @"[""\u003c"",""\u5f20""]";
JsonTextReader reader = new JsonTextReader(new StringReader(json));
-
+
reader.Read();
Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
-
+
reader.Read();
Assert.AreEqual("<", reader.Value);
@@ -782,5 +782,27 @@ bye", reader.Value); Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
}
#endif
+
+ [Test]
+ public void ReadAsDecimal()
+ {
+ string json = @"{""decimal"":-7.92281625142643E+28}";
+
+ JsonTextReader reader = new JsonTextReader(new StringReader(json));
+
+ Assert.IsTrue(reader.Read());
+ Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+ Assert.IsTrue(reader.Read());
+ Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+
+ decimal? d = reader.ReadAsDecimal();
+ Assert.AreEqual(JsonToken.Float, reader.TokenType);
+ Assert.AreEqual(typeof(decimal), reader.ValueType);
+ Assert.AreEqual(-79228162514264300000000000000m, d);
+
+ Assert.IsTrue(reader.Read());
+ Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+ }
}
}
\ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Linq/JTokenTests.cs b/Src/Newtonsoft.Json.Tests/Linq/JTokenTests.cs index 1114d28..c7cf491 100644 --- a/Src/Newtonsoft.Json.Tests/Linq/JTokenTests.cs +++ b/Src/Newtonsoft.Json.Tests/Linq/JTokenTests.cs @@ -60,7 +60,7 @@ namespace Newtonsoft.Json.Tests.Linq Assert.IsTrue(JToken.DeepEquals(new JValue(1), c.Values().ElementAt(0)));
JValue v;
-
+
v = (JValue)JToken.ReadFrom(new JsonTextReader(new StringReader(@"""stringvalue""")));
Assert.AreEqual("stringvalue", (string)v);
@@ -72,6 +72,20 @@ namespace Newtonsoft.Json.Tests.Linq }
[Test]
+ public void Load()
+ {
+ JObject o = (JObject)JToken.Load(new JsonTextReader(new StringReader("{'pie':true}")));
+ Assert.AreEqual(true, (bool)o["pie"]);
+ }
+
+ [Test]
+ public void Parse()
+ {
+ JObject o = (JObject)JToken.Parse("{'pie':true}");
+ Assert.AreEqual(true, (bool)o["pie"]);
+ }
+
+ [Test]
public void Parent()
{
JArray v = new JArray(new JConstructor("TestConstructor"), new JValue(new DateTime(2000, 12, 20)));
diff --git a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs index e31d98a..176fd8e 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs @@ -4015,5 +4015,33 @@ keyword such as type of business."" Assert.AreEqual("Success", deserializedResponse.Name);
Assert.IsTrue(deserializedResponse.Data.DeepEquals(response.Data));
}
+
+ public abstract class Test<T>
+ {
+ public abstract T Value { get; set; }
+ }
+
+ [JsonObject(MemberSerialization.OptIn)]
+ public class DecimalTest : Test<decimal>
+ {
+ protected DecimalTest() { }
+ public DecimalTest(decimal val)
+ {
+ Value = val;
+ }
+
+ [JsonProperty]
+ public override decimal Value { get; set; }
+ }
+
+ [Test]
+ public void OnError()
+ {
+ var data = new DecimalTest(decimal.MinValue);
+ var json = JsonConvert.SerializeObject(data);
+ var obj = JsonConvert.DeserializeObject<DecimalTest>(json);
+
+ Assert.AreEqual(decimal.MinValue, obj.Value);
+ }
}
}
\ No newline at end of file diff --git a/Src/Newtonsoft.Json/Linq/JArray.cs b/Src/Newtonsoft.Json/Linq/JArray.cs index 6b4dc5f..c8d478e 100644 --- a/Src/Newtonsoft.Json/Linq/JArray.cs +++ b/Src/Newtonsoft.Json/Linq/JArray.cs @@ -98,7 +98,7 @@ namespace Newtonsoft.Json.Linq /// </summary>
/// <param name="reader">A <see cref="JsonReader"/> that will be read for the content of the <see cref="JArray"/>.</param>
/// <returns>A <see cref="JArray"/> that contains the JSON that was read from the specified <see cref="JsonReader"/>.</returns>
- public static JArray Load(JsonReader reader)
+ public static new JArray Load(JsonReader reader)
{
if (reader.TokenType == JsonToken.None)
{
@@ -121,7 +121,7 @@ namespace Newtonsoft.Json.Linq /// </summary>
/// <param name="json">A <see cref="String"/> that contains JSON.</param>
/// <returns>A <see cref="JArray"/> populated from the string that contains JSON.</returns>
- public static JArray Parse(string json)
+ public static new JArray Parse(string json)
{
JsonReader jsonReader = new JsonTextReader(new StringReader(json));
diff --git a/Src/Newtonsoft.Json/Linq/JConstructor.cs b/Src/Newtonsoft.Json/Linq/JConstructor.cs index 0f8193c..a875546 100644 --- a/Src/Newtonsoft.Json/Linq/JConstructor.cs +++ b/Src/Newtonsoft.Json/Linq/JConstructor.cs @@ -171,7 +171,7 @@ namespace Newtonsoft.Json.Linq /// </summary>
/// <param name="reader">A <see cref="JsonReader"/> that will be read for the content of the <see cref="JConstructor"/>.</param>
/// <returns>A <see cref="JConstructor"/> that contains the JSON that was read from the specified <see cref="JsonReader"/>.</returns>
- public static JConstructor Load(JsonReader reader)
+ public static new JConstructor Load(JsonReader reader)
{
if (reader.TokenType == JsonToken.None)
{
diff --git a/Src/Newtonsoft.Json/Linq/JObject.cs b/Src/Newtonsoft.Json/Linq/JObject.cs index 4706645..69946f5 100644 --- a/Src/Newtonsoft.Json/Linq/JObject.cs +++ b/Src/Newtonsoft.Json/Linq/JObject.cs @@ -248,7 +248,7 @@ namespace Newtonsoft.Json.Linq /// </summary>
/// <param name="reader">A <see cref="JsonReader"/> that will be read for the content of the <see cref="JObject"/>.</param>
/// <returns>A <see cref="JObject"/> that contains the JSON that was read from the specified <see cref="JsonReader"/>.</returns>
- public static JObject Load(JsonReader reader)
+ public static new JObject Load(JsonReader reader)
{
ValidationUtils.ArgumentNotNull(reader, "reader");
@@ -276,7 +276,7 @@ namespace Newtonsoft.Json.Linq /// </summary>
/// <param name="json">A <see cref="String"/> that contains JSON.</param>
/// <returns>A <see cref="JObject"/> populated from the string that contains JSON.</returns>
- public static JObject Parse(string json)
+ public static new JObject Parse(string json)
{
JsonReader jsonReader = new JsonTextReader(new StringReader(json));
diff --git a/Src/Newtonsoft.Json/Linq/JProperty.cs b/Src/Newtonsoft.Json/Linq/JProperty.cs index 845ee2f..748a3ee 100644 --- a/Src/Newtonsoft.Json/Linq/JProperty.cs +++ b/Src/Newtonsoft.Json/Linq/JProperty.cs @@ -245,7 +245,7 @@ namespace Newtonsoft.Json.Linq /// </summary>
/// <param name="reader">A <see cref="JsonReader"/> that will be read for the content of the <see cref="JProperty"/>.</param>
/// <returns>A <see cref="JProperty"/> that contains the JSON that was read from the specified <see cref="JsonReader"/>.</returns>
- public static JProperty Load(JsonReader reader)
+ public static new JProperty Load(JsonReader reader)
{
if (reader.TokenType == JsonToken.None)
{
diff --git a/Src/Newtonsoft.Json/Linq/JToken.cs b/Src/Newtonsoft.Json/Linq/JToken.cs index 8e63c80..4e07dc6 100644 --- a/Src/Newtonsoft.Json/Linq/JToken.cs +++ b/Src/Newtonsoft.Json/Linq/JToken.cs @@ -1215,6 +1215,32 @@ namespace Newtonsoft.Json.Linq throw new Exception("Error reading JToken from JsonReader. Unexpected token: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
}
+ /// <summary>
+ /// Load a <see cref="JToken"/> from a string that contains JSON.
+ /// </summary>
+ /// <param name="json">A <see cref="String"/> that contains JSON.</param>
+ /// <returns>A <see cref="JToken"/> populated from the string that contains JSON.</returns>
+ public static JToken Parse(string json)
+ {
+ JsonReader jsonReader = new JsonTextReader(new StringReader(json));
+
+ return Load(jsonReader);
+ }
+
+ /// <summary>
+ /// Creates a <see cref="JToken"/> from a <see cref="JsonReader"/>.
+ /// </summary>
+ /// <param name="reader">An <see cref="JsonReader"/> positioned at the token to read into this <see cref="JToken"/>.</param>
+ /// <returns>
+ /// An <see cref="JToken"/> that contains the token and its descendant tokens
+ /// that were read from the reader. The runtime type of the token is determined
+ /// by the token type of the first token encountered in the reader.
+ /// </returns>
+ public static JToken Load(JsonReader reader)
+ {
+ return ReadFrom(reader);
+ }
+
internal void SetLineInfo(IJsonLineInfo lineInfo)
{
if (lineInfo == null || !lineInfo.HasLineInfo())
diff --git a/Src/Newtonsoft.Json/Serialization/DefaultSerializationBinder.cs b/Src/Newtonsoft.Json/Serialization/DefaultSerializationBinder.cs index c4b6145..a1b7ddf 100644 --- a/Src/Newtonsoft.Json/Serialization/DefaultSerializationBinder.cs +++ b/Src/Newtonsoft.Json/Serialization/DefaultSerializationBinder.cs @@ -38,16 +38,13 @@ namespace Newtonsoft.Json.Serialization {
internal static readonly DefaultSerializationBinder Instance = new DefaultSerializationBinder();
- /// <summary>
- /// When overridden in a derived class, controls the binding of a serialized object to a type.
- /// </summary>
- /// <param name="assemblyName">Specifies the <see cref="T:System.Reflection.Assembly"/> name of the serialized object.</param>
- /// <param name="typeName">Specifies the <see cref="T:System.Type"/> name of the serialized object.</param>
- /// <returns>
- /// The type of the object the formatter creates a new instance of.
- /// </returns>
- public override Type BindToType(string assemblyName, string typeName)
+ private readonly ThreadSafeStore<TypeNameKey, Type> _typeCache = new ThreadSafeStore<TypeNameKey, Type>(GetTypeFromTypeNameKey);
+
+ private static Type GetTypeFromTypeNameKey(TypeNameKey typeNameKey)
{
+ string assemblyName = typeNameKey.AssemblyName;
+ string typeName = typeNameKey.TypeName;
+
if (assemblyName != null)
{
Assembly assembly;
@@ -76,5 +73,48 @@ namespace Newtonsoft.Json.Serialization return Type.GetType(typeName);
}
}
+
+ internal struct TypeNameKey : IEquatable<TypeNameKey>
+ {
+ internal readonly string AssemblyName;
+ internal readonly string TypeName;
+
+ public TypeNameKey(string assemblyName, string typeName)
+ {
+ AssemblyName = assemblyName;
+ TypeName = typeName;
+ }
+
+ public override int GetHashCode()
+ {
+ return ((AssemblyName != null) ? AssemblyName.GetHashCode() : 0) ^ ((TypeName != null) ? TypeName.GetHashCode() : 0);
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (!(obj is TypeNameKey))
+ return false;
+
+ return Equals((TypeNameKey)obj);
+ }
+
+ public bool Equals(TypeNameKey other)
+ {
+ return (AssemblyName == other.AssemblyName && TypeName == other.TypeName);
+ }
+ }
+
+ /// <summary>
+ /// When overridden in a derived class, controls the binding of a serialized object to a type.
+ /// </summary>
+ /// <param name="assemblyName">Specifies the <see cref="T:System.Reflection.Assembly"/> name of the serialized object.</param>
+ /// <param name="typeName">Specifies the <see cref="T:System.Type"/> name of the serialized object.</param>
+ /// <returns>
+ /// The type of the object the formatter creates a new instance of.
+ /// </returns>
+ public override Type BindToType(string assemblyName, string typeName)
+ {
+ return _typeCache.Get(new TypeNameKey(assemblyName, typeName));
+ }
}
}
\ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs index 0d2b083..2a8e494 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs @@ -863,8 +863,6 @@ namespace Newtonsoft.Json.Serialization {
case JsonToken.PropertyName:
string memberName = reader.Value.ToString();
- if (!reader.Read())
- throw new JsonSerializationException("Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName));
// attempt exact case match first
// then try match ignoring case
@@ -872,6 +870,9 @@ namespace Newtonsoft.Json.Serialization if (property != null)
{
+ if (!ReadForType(reader, property.PropertyType, property.Converter))
+ throw new JsonSerializationException("Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName));
+
if (!property.Ignored)
propertyValues[property] = CreateValueProperty(reader, property, null, true, null);
else
@@ -879,6 +880,9 @@ namespace Newtonsoft.Json.Serialization }
else
{
+ if (!reader.Read())
+ throw new JsonSerializationException("Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName));
+
if (Serializer.MissingMemberHandling == MissingMemberHandling.Error)
throw new JsonSerializationException("Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, memberName, objectType.Name));
|