diff --git a/Src/Newtonsoft.Json.Tests/Converters/XmlNodeConverterTest.cs b/Src/Newtonsoft.Json.Tests/Converters/XmlNodeConverterTest.cs
index 8df81e94..58d87a54 100644
--- a/Src/Newtonsoft.Json.Tests/Converters/XmlNodeConverterTest.cs
+++ b/Src/Newtonsoft.Json.Tests/Converters/XmlNodeConverterTest.cs
@@ -2338,6 +2338,22 @@ namespace Newtonsoft.Json.Tests.Converters
Assert.AreEqual(@"AsdAAAadad", xmlBack.OuterXml);
}
+
+#if !(NET20 || NET35 || PORTABLE || PORTABLE40)
+ [Test]
+ public void DeserializeBigInteger()
+ {
+ var json = "{\"DocumentId\":13779965364495889899 }";
+
+ XmlDocument node = JsonConvert.DeserializeXmlNode(json);
+
+ Assert.AreEqual("13779965364495889899", node.OuterXml);
+
+ string json2 = JsonConvert.SerializeXmlNode(node);
+
+ Assert.AreEqual(@"{""DocumentId"":""13779965364495889899""}", json2);
+ }
+#endif
}
}
#endif
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json.Tests/Serialization/ExtensionDataTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/ExtensionDataTests.cs
index 4da7c9a2..512e07e7 100644
--- a/Src/Newtonsoft.Json.Tests/Serialization/ExtensionDataTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Serialization/ExtensionDataTests.cs
@@ -48,7 +48,7 @@ namespace Newtonsoft.Json.Tests.Serialization
public class CustomDictionary : IDictionary
{
private readonly IDictionary _inner = new Dictionary();
-
+
public void Add(string key, object value)
{
_inner.Add(key, value);
@@ -235,7 +235,7 @@ namespace Newtonsoft.Json.Tests.Serialization
}
#pragma warning disable 649
- class ExtendedObject
+ private class ExtendedObject
{
[JsonExtensionData]
internal IDictionary _additionalData;
@@ -744,5 +744,90 @@ namespace Newtonsoft.Json.Tests.Serialization
Assert.AreEqual(1, c.CustomFields.Count);
Assert.AreEqual("Testing", (string)c.CustomFields["CustomField1"]);
}
+
+ public class DocNoSetter
+ {
+ private readonly JObject _content;
+
+ public DocNoSetter()
+ {
+ }
+
+ public DocNoSetter(JObject content)
+ {
+ _content = content;
+ }
+
+ [JsonProperty("_name")]
+ public string Name { get; set; }
+
+ [JsonExtensionData]
+ public JObject Content
+ {
+ get { return _content; }
+ }
+ }
+
+ [Test]
+ public void SerializeExtensionData_NoSetter()
+ {
+ string json = JsonConvert.SerializeObject(new DocNoSetter(new JObject(new JProperty("Property1", 123)))
+ {
+ Name = "documentName"
+ });
+ Assert.AreEqual(@"{""_name"":""documentName"",""Property1"":123}", json);
+ }
+
+ [Test]
+ public void SerializeExtensionData_NoSetterAndNoValue()
+ {
+ string json = JsonConvert.SerializeObject(new DocNoSetter(null)
+ {
+ Name = "documentName"
+ });
+ Assert.AreEqual(@"{""_name"":""documentName""}", json);
+ }
+
+ [Test]
+ public void DeserializeExtensionData_NoSetterAndNoExtensionData()
+ {
+ DocNoSetter doc = JsonConvert.DeserializeObject(@"{""_name"":""documentName""}");
+
+ Assert.AreEqual("documentName", doc.Name);
+ }
+
+ [Test]
+ public void DeserializeExtensionData_NoSetterAndWithExtensionData()
+ {
+ try
+ {
+ JsonConvert.DeserializeObject(@"{""_name"":""documentName"",""Property1"":123}");
+ }
+ catch (JsonSerializationException ex)
+ {
+ Assert.AreEqual("Error setting value in extension data for type 'Newtonsoft.Json.Tests.Serialization.ExtensionDataTests+DocNoSetter'. Path 'Property1', line 1, position 39.", ex.Message);
+ Assert.AreEqual("Cannot set value onto extension data member 'Content'. The extension data collection is null and it cannot be set.", ex.InnerException.Message);
+ }
+ }
+
+ public class DocNoGetter
+ {
+ [JsonExtensionData]
+ public JObject Content
+ {
+ set { }
+ }
+ }
+
+ [Test]
+ public void SerializeExtensionData_NoGetter()
+ {
+ ExceptionAssert.Throws(
+ () =>
+ {
+ JsonConvert.SerializeObject(new DocNoGetter());
+ },
+ "Invalid extension data attribute on 'Newtonsoft.Json.Tests.Serialization.ExtensionDataTests+DocNoGetter'. Member 'Content' must have a getter.");
+ }
}
}
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs b/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs
index 9607d6a0..aa47cffa 100644
--- a/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs
+++ b/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs
@@ -23,6 +23,7 @@
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
+using System.Numerics;
#if !PORTABLE40
using System;
using System.Collections.Generic;
@@ -1417,6 +1418,11 @@ namespace Newtonsoft.Json.Converters
}
else if (reader.TokenType == JsonToken.Integer)
{
+#if !(NET20 || NET35 || PORTABLE || PORTABLE40)
+ if (reader.Value is BigInteger)
+ return ((BigInteger)reader.Value).ToString(CultureInfo.InvariantCulture);
+#endif
+
return XmlConvert.ToString(Convert.ToInt64(reader.Value, CultureInfo.InvariantCulture));
}
else if (reader.TokenType == JsonToken.Float)
diff --git a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs
index 797bfa52..7a67ecc6 100644
--- a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs
+++ b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs
@@ -25,6 +25,7 @@
using System;
using System.Collections;
+using Newtonsoft.Json.Schema;
#if !(NET35 || NET20 || PORTABLE || PORTABLE40)
using System.Collections.Concurrent;
#endif
@@ -438,6 +439,9 @@ namespace Newtonsoft.Json.Serialization
if (!m.IsDefined(typeof(JsonExtensionDataAttribute), false))
return false;
+ if (!ReflectionUtils.CanReadMemberValue(m, true))
+ throw new JsonException("Invalid extension data attribute on '{0}'. Member '{1}' must have a getter.".FormatWith(CultureInfo.InvariantCulture, GetClrTypeFullName(m.DeclaringType), m.Name));
+
Type t = ReflectionUtils.GetMemberUnderlyingType(m);
Type dictionaryType;
@@ -479,10 +483,12 @@ namespace Newtonsoft.Json.Serialization
else
createdType = t;
- MethodInfo addMethod = t.GetMethod("Add", new[] { keyType, valueType });
Func