-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:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user