diff --git a/Src/Newtonsoft.Json.Tests/Linq/JObjectTests.cs b/Src/Newtonsoft.Json.Tests/Linq/JObjectTests.cs index 4834b89c..d82737a4 100644 --- a/Src/Newtonsoft.Json.Tests/Linq/JObjectTests.cs +++ b/Src/Newtonsoft.Json.Tests/Linq/JObjectTests.cs @@ -410,5 +410,23 @@ Parameter name: arrayIndex")] i++; } } + + [Test] + public void WriteObjectNullStringValue() + { + string s = null; + JValue v = new JValue(s); + Assert.AreEqual(null, v.Value); + Assert.AreEqual(JTokenType.String, v.Type); + + JObject o = new JObject(); + o["title"] = v; + + string output = o.ToString(); + + Assert.AreEqual(@"{ + ""title"": null +}", output); + } } } diff --git a/Src/Newtonsoft.Json.Tests/Linq/JTokenTests.cs b/Src/Newtonsoft.Json.Tests/Linq/JTokenTests.cs index fc57c825..3dd5b981 100644 --- a/Src/Newtonsoft.Json.Tests/Linq/JTokenTests.cs +++ b/Src/Newtonsoft.Json.Tests/Linq/JTokenTests.cs @@ -235,6 +235,11 @@ namespace Newtonsoft.Json.Tests.Linq Assert.AreEqual(ulong.MaxValue, (ulong)new JValue(ulong.MaxValue)); Assert.AreEqual(ulong.MaxValue, (ulong)new JProperty("Test", new JValue(ulong.MaxValue))); Assert.AreEqual(null, (string)new JValue((string)null)); + Assert.AreEqual(5m, (decimal)(new JValue(5L))); + Assert.AreEqual(5m, (decimal?)(new JValue(5L))); + Assert.AreEqual(5f, (float)(new JValue(5L))); + Assert.AreEqual(5f, (float)(new JValue(5m))); + Assert.AreEqual(5f, (float?)(new JValue(5m))); } [Test] diff --git a/Src/Newtonsoft.Json/Linq/JToken.cs b/Src/Newtonsoft.Json/Linq/JToken.cs index 08d223eb..e5395907 100644 --- a/Src/Newtonsoft.Json/Linq/JToken.cs +++ b/Src/Newtonsoft.Json/Linq/JToken.cs @@ -517,7 +517,7 @@ namespace Newtonsoft.Json.Linq if (v == null || !ValidateFloat(v, true)) throw new ArgumentException("Can not convert {0} to Decimal.".FormatWith(CultureInfo.InvariantCulture, GetType(v))); - return (decimal?)v.Value; + return (v.Value != null) ? (decimal?)Convert.ToDecimal(v.Value) : null; } /// @@ -613,7 +613,7 @@ namespace Newtonsoft.Json.Linq if (v == null || !ValidateFloat(v, true)) throw new ArgumentException("Can not convert {0} to Single.".FormatWith(CultureInfo.InvariantCulture, GetType(v))); - return (float?)v.Value; + return (v.Value != null) ? (float?)Convert.ToSingle(v.Value) : null; } /// @@ -627,7 +627,7 @@ namespace Newtonsoft.Json.Linq if (v == null || !ValidateFloat(v, false)) throw new ArgumentException("Can not convert {0} to Decimal.".FormatWith(CultureInfo.InvariantCulture, GetType(v))); - return (decimal)v.Value; + return Convert.ToDecimal(v.Value); } /// diff --git a/Src/Newtonsoft.Json/Linq/JValue.cs b/Src/Newtonsoft.Json/Linq/JValue.cs index bccfa8f2..a9ab3e81 100644 --- a/Src/Newtonsoft.Json/Linq/JValue.cs +++ b/Src/Newtonsoft.Json/Linq/JValue.cs @@ -264,15 +264,14 @@ namespace Newtonsoft.Json.Linq } } - private static void WriteConvertableValue(JsonWriter writer, IList converters, Action _defaultWrite, object value) + private static void WriteConvertableValue(JsonWriter writer, IList converters, Action defaultWrite, object value) { JsonConverter matchingConverter; - JsonSerializer.HasMatchingConverter(converters, value.GetType(), out matchingConverter); - if (matchingConverter != null) + if (value != null && JsonSerializer.HasMatchingConverter(converters, value.GetType(), out matchingConverter)) matchingConverter.WriteJson(writer, value); else - _defaultWrite(value); + defaultWrite(value); } /// @@ -294,7 +293,7 @@ namespace Newtonsoft.Json.Linq WriteConvertableValue(writer, converters, v => writer.WriteValue(Convert.ToDouble(v, CultureInfo.InvariantCulture)), _value); break; case JTokenType.String: - WriteConvertableValue(writer, converters, v => writer.WriteValue(v.ToString()), _value); + WriteConvertableValue(writer, converters, v => writer.WriteValue((v != null) ? v.ToString() : null), _value); break; case JTokenType.Boolean: WriteConvertableValue(writer, converters, v => writer.WriteValue(Convert.ToBoolean(v, CultureInfo.InvariantCulture)), _value);