-Added additional ToString overloads to JValue
-Fixed poor error message when dynamic type cannot be created during deserialization -Fixed error when setting a null value on a dynamic type during deserialization -Fixed JsonTextReader.ReadAsDecimal not attempting to convert string values to decimal
This commit is contained in:
@@ -185,7 +185,7 @@ namespace Newtonsoft.Json.Tests.Linq
|
||||
|
||||
Assert.AreEqual("", d.Null.ToString());
|
||||
Assert.AreEqual("1", d.Integer.ToString());
|
||||
Assert.AreEqual("1.1", d.Float.ToString());
|
||||
Assert.AreEqual("1.1", d.Float.ToString(CultureInfo.InvariantCulture));
|
||||
Assert.AreEqual("12/29/2000 23:51:10", d.DateTime.ToString(null, CultureInfo.InvariantCulture));
|
||||
Assert.AreEqual("True", d.Boolean.ToString());
|
||||
Assert.AreEqual("A string lol!", d.String.ToString());
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using NUnit.Framework;
|
||||
@@ -285,7 +286,7 @@ keyword such as type of business.""
|
||||
1264118400000
|
||||
)", o.Property("Establised").Value.ToString());
|
||||
Assert.AreEqual(@"""Width"": 1.1", o.Property("Width").ToString());
|
||||
Assert.AreEqual(@"1.1", o.Property("Width").Value.ToString());
|
||||
Assert.AreEqual(@"1.1", ((JValue)o.Property("Width").Value).ToString(CultureInfo.InvariantCulture));
|
||||
Assert.AreEqual(@"""Open"": false", o.Property("Open").ToString());
|
||||
Assert.AreEqual(@"False", o.Property("Open").Value.ToString());
|
||||
|
||||
|
||||
@@ -182,6 +182,103 @@ namespace Newtonsoft.Json.Tests.Serialization
|
||||
Assert.AreEqual("Child text!", n.DynamicChildObject.Text);
|
||||
Assert.AreEqual(int.MinValue, n.DynamicChildObject.Integer);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "Unable to find a default constructor to use for type System.Dynamic.DynamicObject.")]
|
||||
public void NoPublicDefaultConstructor()
|
||||
{
|
||||
var settings = new JsonSerializerSettings();
|
||||
settings.NullValueHandling = NullValueHandling.Ignore;
|
||||
var json = @"{
|
||||
""contributors"": null
|
||||
}";
|
||||
|
||||
JsonConvert.DeserializeObject<DynamicObject>(json, settings);
|
||||
}
|
||||
|
||||
public class DictionaryDynamicObject : DynamicObject
|
||||
{
|
||||
public IDictionary<string, object> Values { get; private set; }
|
||||
|
||||
protected DictionaryDynamicObject()
|
||||
{
|
||||
Values = new Dictionary<string, object>();
|
||||
}
|
||||
|
||||
public override bool TrySetMember(SetMemberBinder binder, object value)
|
||||
{
|
||||
Values[binder.Name] = value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AllowNonPublicDefaultConstructor()
|
||||
{
|
||||
var settings = new JsonSerializerSettings();
|
||||
settings.ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor;
|
||||
|
||||
var json = @"{
|
||||
""contributors"": null,
|
||||
""retweeted"": false,
|
||||
""text"": ""Guys SX4 diesel is launched.what are your plans?catch us at #facebook http://bit.ly/dV3H1a #auto #car #maruti #india #delhi"",
|
||||
""in_reply_to_user_id_str"": null,
|
||||
""retweet_count"": 0,
|
||||
""geo"": null,
|
||||
""id_str"": ""40678260320768000"",
|
||||
""in_reply_to_status_id"": null,
|
||||
""source"": ""<a href=\""http://www.tweetdeck.com\"" rel=\""nofollow\"">TweetDeck</a>"",
|
||||
""created_at"": ""Thu Feb 24 07:43:47 +0000 2011"",
|
||||
""place"": null,
|
||||
""coordinates"": null,
|
||||
""truncated"": false,
|
||||
""favorited"": false,
|
||||
""user"": {
|
||||
""profile_background_image_url"": ""http://a1.twimg.com/profile_background_images/206944715/twitter_bg.jpg"",
|
||||
""url"": ""http://bit.ly/dcFwWC"",
|
||||
""screen_name"": ""marutisuzukisx4"",
|
||||
""verified"": false,
|
||||
""friends_count"": 45,
|
||||
""description"": ""This is the Official Maruti Suzuki SX4 Twitter ID! Men are Back - mail us on social (at) sx4bymaruti (dot) com"",
|
||||
""follow_request_sent"": null,
|
||||
""time_zone"": ""Chennai"",
|
||||
""profile_text_color"": ""333333"",
|
||||
""location"": ""India"",
|
||||
""notifications"": null,
|
||||
""profile_sidebar_fill_color"": ""efefef"",
|
||||
""id_str"": ""196143889"",
|
||||
""contributors_enabled"": false,
|
||||
""lang"": ""en"",
|
||||
""profile_background_tile"": false,
|
||||
""created_at"": ""Tue Sep 28 12:55:15 +0000 2010"",
|
||||
""followers_count"": 117,
|
||||
""show_all_inline_media"": true,
|
||||
""listed_count"": 1,
|
||||
""geo_enabled"": true,
|
||||
""profile_link_color"": ""009999"",
|
||||
""profile_sidebar_border_color"": ""eeeeee"",
|
||||
""protected"": false,
|
||||
""name"": ""Maruti Suzuki SX4"",
|
||||
""statuses_count"": 637,
|
||||
""following"": null,
|
||||
""profile_use_background_image"": true,
|
||||
""profile_image_url"": ""http://a3.twimg.com/profile_images/1170694644/Slide1_normal.JPG"",
|
||||
""id"": 196143889,
|
||||
""is_translator"": false,
|
||||
""utc_offset"": 19800,
|
||||
""favourites_count"": 0,
|
||||
""profile_background_color"": ""131516""
|
||||
},
|
||||
""in_reply_to_screen_name"": null,
|
||||
""id"": 40678260320768000,
|
||||
""in_reply_to_status_id_str"": null,
|
||||
""in_reply_to_user_id"": null
|
||||
}";
|
||||
|
||||
DictionaryDynamicObject foo = JsonConvert.DeserializeObject<DictionaryDynamicObject>(json, settings);
|
||||
|
||||
Assert.AreEqual(false, foo.Values["retweeted"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -28,6 +28,7 @@ using System.Collections.Generic;
|
||||
#if !SILVERLIGHT && !PocketPC && !NET20
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using System.Web.Script.Serialization;
|
||||
#endif
|
||||
using System.Text;
|
||||
@@ -4178,5 +4179,29 @@ keyword such as type of business.""
|
||||
""Name"": null
|
||||
}", json);
|
||||
}
|
||||
|
||||
public class DeserializeStringConvert
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public int Age { get; set; }
|
||||
public double Height { get; set; }
|
||||
public decimal Price { get; set; }
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DeserializeStringEnglish()
|
||||
{
|
||||
string json = @"{
|
||||
'Name': 'James Hughes',
|
||||
'Age': '40',
|
||||
'Height': '44.4',
|
||||
'Price': '4'
|
||||
}";
|
||||
|
||||
DeserializeStringConvert p = JsonConvert.DeserializeObject<DeserializeStringConvert>(json);
|
||||
Assert.AreEqual(40, p.Age);
|
||||
Assert.AreEqual(44.4, p.Height);
|
||||
Assert.AreEqual(4d, p.Price);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -348,6 +348,13 @@ namespace Newtonsoft.Json
|
||||
if (TokenType == JsonToken.Float)
|
||||
return (decimal?)Value;
|
||||
|
||||
decimal d;
|
||||
if (TokenType == JsonToken.String && decimal.TryParse((string)Value, NumberStyles.Number, CultureInfo.InvariantCulture, out d))
|
||||
{
|
||||
SetToken(JsonToken.Float, d);
|
||||
return d;
|
||||
}
|
||||
|
||||
throw CreateJsonReaderException("Unexpected token when reading decimal: {0}. Line {1}, position {2}.", TokenType, _currentLineNumber, _currentLinePosition);
|
||||
}
|
||||
|
||||
|
||||
@@ -458,6 +458,30 @@ namespace Newtonsoft.Json.Linq
|
||||
return _value.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="System.String"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <param name="format">The format.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="System.String"/> that represents this instance.
|
||||
/// </returns>
|
||||
public string ToString(string format)
|
||||
{
|
||||
return ToString(format, CultureInfo.CurrentCulture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="System.String"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <param name="formatProvider">The format provider.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="System.String"/> that represents this instance.
|
||||
/// </returns>
|
||||
public string ToString(IFormatProvider formatProvider)
|
||||
{
|
||||
return ToString(null, formatProvider);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="System.String"/> that represents this instance.
|
||||
/// </summary>
|
||||
|
||||
@@ -228,7 +228,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
case JsonToken.Boolean:
|
||||
case JsonToken.Date:
|
||||
case JsonToken.Bytes:
|
||||
return EnsureType(reader.Value, objectType);
|
||||
return EnsureType(reader.Value, CultureInfo.InvariantCulture, objectType);
|
||||
case JsonToken.String:
|
||||
// convert empty string to null automatically for nullable types
|
||||
if (string.IsNullOrEmpty((string)reader.Value) &&
|
||||
@@ -240,7 +240,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
if (objectType == typeof(byte[]))
|
||||
return Convert.FromBase64String((string)reader.Value);
|
||||
|
||||
return EnsureType(reader.Value, objectType);
|
||||
return EnsureType(reader.Value, CultureInfo.InvariantCulture, objectType);
|
||||
case JsonToken.StartConstructor:
|
||||
case JsonToken.EndConstructor:
|
||||
string constructorName = reader.Value.ToString();
|
||||
@@ -251,7 +251,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
if (objectType == typeof (DBNull))
|
||||
return DBNull.Value;
|
||||
|
||||
return EnsureType(reader.Value, objectType);
|
||||
return EnsureType(reader.Value, CultureInfo.InvariantCulture, objectType);
|
||||
case JsonToken.Raw:
|
||||
return new JRaw((string)reader.Value);
|
||||
case JsonToken.Comment:
|
||||
@@ -463,7 +463,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
);
|
||||
}
|
||||
|
||||
private object EnsureType(object value, Type targetType)
|
||||
private object EnsureType(object value, CultureInfo culture, Type targetType)
|
||||
{
|
||||
if (targetType == null)
|
||||
return value;
|
||||
@@ -476,7 +476,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
{
|
||||
try
|
||||
{
|
||||
return ConvertUtils.ConvertOrCast(value, CultureInfo.InvariantCulture, targetType);
|
||||
return ConvertUtils.ConvertOrCast(value, culture, targetType);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -612,7 +612,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
object keyValue;
|
||||
try
|
||||
{
|
||||
keyValue = EnsureType(reader.Value, contract.DictionaryKeyType);
|
||||
keyValue = EnsureType(reader.Value, CultureInfo.InvariantCulture, contract.DictionaryKeyType);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -776,9 +776,9 @@ namespace Newtonsoft.Json.Serialization
|
||||
|
||||
if (contract.DefaultCreator != null &&
|
||||
(!contract.DefaultCreatorNonPublic || Serializer.ConstructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor))
|
||||
{
|
||||
newObject = (IDynamicMetaObjectProvider)contract.DefaultCreator();
|
||||
}
|
||||
else
|
||||
throw new JsonSerializationException("Unable to find a default constructor to use for type {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
|
||||
|
||||
if (id != null)
|
||||
Serializer.ReferenceResolver.AddReference(id, newObject);
|
||||
|
||||
@@ -98,6 +98,8 @@ namespace Newtonsoft.Json.Utilities
|
||||
|
||||
public static bool TryGetMember(this IDynamicMetaObjectProvider dynamicProvider, string name, out object value)
|
||||
{
|
||||
ValidationUtils.ArgumentNotNull(dynamicProvider, "dynamicProvider");
|
||||
|
||||
GetMemberBinder getMemberBinder = (GetMemberBinder) BinderWrapper.GetMember(name, typeof (DynamicUtils));
|
||||
|
||||
CallSite<Func<CallSite, object, object>> callSite = CallSite<Func<CallSite, object, object>>.Create(new NoThrowGetBinderMember(getMemberBinder));
|
||||
@@ -118,7 +120,9 @@ namespace Newtonsoft.Json.Utilities
|
||||
|
||||
public static bool TrySetMember(this IDynamicMetaObjectProvider dynamicProvider, string name, object value)
|
||||
{
|
||||
SetMemberBinder binder = (SetMemberBinder) BinderWrapper.SetMember(name, value.GetType());
|
||||
ValidationUtils.ArgumentNotNull(dynamicProvider, "dynamicProvider");
|
||||
|
||||
SetMemberBinder binder = (SetMemberBinder)BinderWrapper.SetMember(name, typeof(DynamicUtils));
|
||||
|
||||
var setterSite = CallSite<Func<CallSite, object, object, object>>.Create(new NoThrowSetBinderMember(binder));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user