-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
This commit is contained in:
JamesNK
2011-01-08 04:39:33 +00:00
parent 0fb78fdb91
commit ac6c65f48a
11 changed files with 159 additions and 24 deletions
+2 -1
View File
@@ -2,7 +2,8 @@
<package>
<metadata>
<id>Newtonsoft.Json</id>
<version>3.5.8</version>
<title>Newtonsoft.Json</title>
<version>4.0.1</version>
<authors>James Newton-King</authors>
<description>Json.NET is a popular high-performance JSON framework for .NET</description>
<language>en-US</language>
@@ -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);
}
}
}
+15 -1
View File
@@ -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);
@@ -71,6 +71,20 @@ namespace Newtonsoft.Json.Tests.Linq
Assert.AreEqual(1.1, (double)v);
}
[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()
{
@@ -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);
}
}
}
+2 -2
View File
@@ -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));
+1 -1
View File
@@ -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)
{
+2 -2
View File
@@ -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));
+1 -1
View File
@@ -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)
{
+26
View File
@@ -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())
@@ -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));
}
}
}
@@ -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));