diff --git a/Doc/Samples/Serializer/CustomJsonConverterGeneric.aml b/Doc/Samples/Serializer/CustomJsonConverterGeneric.aml
new file mode 100644
index 00000000..9d541152
--- /dev/null
+++ b/Doc/Samples/Serializer/CustomJsonConverterGeneric.aml
@@ -0,0 +1,16 @@
+
+
+
+
+ This sample creates a custom T:Newtonsoft.Json.JsonConverter{T}
+ that overrides serialization to add a keys property.
+
+
+
+
\ No newline at end of file
diff --git a/Doc/doc.content b/Doc/doc.content
index 991d7d78..466c8bb8 100644
--- a/Doc/doc.content
+++ b/Doc/doc.content
@@ -63,6 +63,7 @@
+
@@ -71,7 +72,7 @@
-
+
@@ -164,4 +165,4 @@
-
+
\ No newline at end of file
diff --git a/Doc/doc.shfbproj b/Doc/doc.shfbproj
index d0744a5f..6e5a73ca 100644
--- a/Doc/doc.shfbproj
+++ b/Doc/doc.shfbproj
@@ -100,6 +100,7 @@
+
diff --git a/Src/Newtonsoft.Json.Tests/Converters/DataSetConverterTests.cs b/Src/Newtonsoft.Json.Tests/Converters/DataSetConverterTests.cs
index 41b8528e..dabbd100 100644
--- a/Src/Newtonsoft.Json.Tests/Converters/DataSetConverterTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Converters/DataSetConverterTests.cs
@@ -36,6 +36,7 @@ using NUnit.Framework;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json.Tests.TestObjects;
using System.Data;
+using System.IO;
namespace Newtonsoft.Json.Tests.Converters
{
@@ -107,6 +108,18 @@ namespace Newtonsoft.Json.Tests.Converters
public DataSet Set { get; set; }
}
+ [Test]
+ public void WriteJsonNull()
+ {
+ StringWriter sw = new StringWriter();
+ JsonTextWriter jsonWriter = new JsonTextWriter(sw);
+
+ DataSetConverter converter = new DataSetConverter();
+ converter.WriteJson(jsonWriter, null, null);
+
+ StringAssert.AreEqual(@"null", sw.ToString());
+ }
+
[Test]
public void SerializeNull()
{
diff --git a/Src/Newtonsoft.Json.Tests/Converters/DataTableConverterTests.cs b/Src/Newtonsoft.Json.Tests/Converters/DataTableConverterTests.cs
index 1539564e..98b6169d 100644
--- a/Src/Newtonsoft.Json.Tests/Converters/DataTableConverterTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Converters/DataTableConverterTests.cs
@@ -45,6 +45,18 @@ namespace Newtonsoft.Json.Tests.Converters
{
public class DataTableConverterTests : TestFixtureBase
{
+ [Test]
+ public void WriteJsonNull()
+ {
+ StringWriter sw = new StringWriter();
+ JsonTextWriter jsonWriter = new JsonTextWriter(sw);
+
+ DataTableConverter converter = new DataTableConverter();
+ converter.WriteJson(jsonWriter, null, null);
+
+ StringAssert.AreEqual(@"null", sw.ToString());
+ }
+
[Test]
public void Deserialize()
{
diff --git a/Src/Newtonsoft.Json.Tests/Converters/RegexConverterTests.cs b/Src/Newtonsoft.Json.Tests/Converters/RegexConverterTests.cs
index fc5a6654..71a8cb3e 100644
--- a/Src/Newtonsoft.Json.Tests/Converters/RegexConverterTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Converters/RegexConverterTests.cs
@@ -50,6 +50,18 @@ namespace Newtonsoft.Json.Tests.Converters
public Regex Regex { get; set; }
}
+ [Test]
+ public void WriteJsonNull()
+ {
+ StringWriter sw = new StringWriter();
+ JsonTextWriter jsonWriter = new JsonTextWriter(sw);
+
+ RegexConverter converter = new RegexConverter();
+ converter.WriteJson(jsonWriter, null, null);
+
+ StringAssert.AreEqual(@"null", sw.ToString());
+ }
+
[Test]
public void SerializeToText()
{
diff --git a/Src/Newtonsoft.Json.Tests/Converters/VersionConverterTests.cs b/Src/Newtonsoft.Json.Tests/Converters/VersionConverterTests.cs
index 778d0826..65593347 100644
--- a/Src/Newtonsoft.Json.Tests/Converters/VersionConverterTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Converters/VersionConverterTests.cs
@@ -24,6 +24,7 @@
#endregion
using System;
+using System.IO;
using Newtonsoft.Json.Converters;
#if DNXCORE50
using Xunit;
@@ -92,6 +93,18 @@ namespace Newtonsoft.Json.Tests.Converters
}
}
+ [Test]
+ public void WriteJsonNull()
+ {
+ StringWriter sw = new StringWriter();
+ JsonTextWriter jsonWriter = new JsonTextWriter(sw);
+
+ VersionConverter converter = new VersionConverter();
+ converter.WriteJson(jsonWriter, null, null);
+
+ StringAssert.AreEqual(@"null", sw.ToString());
+ }
+
[Test]
public void SerializeVersionClass()
{
diff --git a/Src/Newtonsoft.Json.Tests/Converters/XmlNodeConverterTest.cs b/Src/Newtonsoft.Json.Tests/Converters/XmlNodeConverterTest.cs
index 3d092474..4dc7f583 100644
--- a/Src/Newtonsoft.Json.Tests/Converters/XmlNodeConverterTest.cs
+++ b/Src/Newtonsoft.Json.Tests/Converters/XmlNodeConverterTest.cs
@@ -151,6 +151,18 @@ namespace Newtonsoft.Json.Tests.Converters
return sw.ToString();
}
+ [Test]
+ public void WriteJsonNull()
+ {
+ StringWriter sw = new StringWriter();
+ JsonTextWriter jsonWriter = new JsonTextWriter(sw);
+
+ XmlNodeConverter converter = new XmlNodeConverter();
+ converter.WriteJson(jsonWriter, null, null);
+
+ StringAssert.AreEqual(@"null", sw.ToString());
+ }
+
#if !NET20
[Test]
public void SerializeDollarProperty()
diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/CustomJsonConverterGeneric.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/CustomJsonConverterGeneric.cs
new file mode 100644
index 00000000..4fb780ce
--- /dev/null
+++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/CustomJsonConverterGeneric.cs
@@ -0,0 +1,93 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using Newtonsoft.Json.Linq;
+using System;
+using System.Collections.Generic;
+using System.Text;
+#if DNXCORE50
+using Xunit;
+using Test = Xunit.FactAttribute;
+using Assert = Newtonsoft.Json.Tests.XUnitAssert;
+#else
+using NUnit.Framework;
+#endif
+
+namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer
+{
+ [TestFixture]
+ public class CustomJsonConverterGeneric : TestFixtureBase
+ {
+ #region Types
+ public class VersionConverter : JsonConverter
+ {
+ public override void WriteJson(JsonWriter writer, Version value, JsonSerializer serializer)
+ {
+ writer.WriteValue(value.ToString());
+ }
+
+ public override Version ReadJson(JsonReader reader, Type objectType, Version existingValue, bool hasExistingValue, JsonSerializer serializer)
+ {
+ string s = (string)reader.Value;
+
+ return new Version(s);
+ }
+ }
+
+ public class NuGetPackage
+ {
+ public string PackageId { get; set; }
+ public Version Version { get; set; }
+ }
+ #endregion
+
+ [Test]
+ public void Example()
+ {
+ #region Usage
+ NuGetPackage p1 = new NuGetPackage
+ {
+ PackageId = "Newtonsoft.Json",
+ Version = new Version(10, 0, 4)
+ };
+
+ string json = JsonConvert.SerializeObject(p1, Formatting.Indented, new VersionConverter());
+
+ Console.WriteLine(json);
+ // {
+ // "PackageId": "Newtonsoft.Json",
+ // "Version": "10.0.4"
+ // }
+
+ NuGetPackage p2 = JsonConvert.DeserializeObject(json, new VersionConverter());
+
+ Console.WriteLine(p2.Version.ToString());
+ // James
+ #endregion
+
+ Assert.AreEqual("10.0.4", p2.Version.ToString());
+ }
+ }
+}
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Converters/BsonObjectIdConverter.cs b/Src/Newtonsoft.Json/Converters/BsonObjectIdConverter.cs
index 51e03092..533e113d 100644
--- a/Src/Newtonsoft.Json/Converters/BsonObjectIdConverter.cs
+++ b/Src/Newtonsoft.Json/Converters/BsonObjectIdConverter.cs
@@ -34,7 +34,7 @@ namespace Newtonsoft.Json.Converters
/// Converts a to and from JSON and BSON.
///
[Obsolete("BSON reading and writing has been moved to its own package. See https://www.nuget.org/packages/Newtonsoft.Json.Bson for more details.")]
- public class BsonObjectIdConverter : JsonConverter
+ public class BsonObjectIdConverter : JsonConverter
{
///
/// Writes the JSON representation of the object.
@@ -42,22 +42,18 @@ namespace Newtonsoft.Json.Converters
/// The to write to.
/// The value.
/// The calling serializer.
- public override void WriteJson(JsonWriter writer, BsonObjectId value, JsonSerializer serializer)
+ public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
- if (value == null)
- {
- writer.WriteNull();
- return;
- }
+ BsonObjectId objectId = (BsonObjectId)value;
BsonWriter bsonWriter = writer as BsonWriter;
if (bsonWriter != null)
{
- bsonWriter.WriteObjectId(value.Value);
+ bsonWriter.WriteObjectId(objectId.Value);
}
else
{
- writer.WriteValue(value.Value);
+ writer.WriteValue(objectId.Value);
}
}
@@ -66,11 +62,10 @@ namespace Newtonsoft.Json.Converters
///
/// The to read from.
/// Type of the object.
- /// The existing value of object being read. If there is no existing value then null will be used.
- /// The existing value has a value.
+ /// The existing value of object being read.
/// The calling serializer.
/// The object value.
- public override BsonObjectId ReadJson(JsonReader reader, Type objectType, BsonObjectId existingValue, bool hasExistingValue, JsonSerializer serializer)
+ public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType != JsonToken.Bytes)
{
@@ -81,5 +76,17 @@ namespace Newtonsoft.Json.Converters
return new BsonObjectId(value);
}
+
+ ///
+ /// Determines whether this instance can convert the specified object type.
+ ///
+ /// Type of the object.
+ ///
+ /// true if this instance can convert the specified object type; otherwise, false.
+ ///
+ public override bool CanConvert(Type objectType)
+ {
+ return (objectType == typeof(BsonObjectId));
+ }
}
}
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Converters/DataSetConverter.cs b/Src/Newtonsoft.Json/Converters/DataSetConverter.cs
index e41f19ce..7605f9c4 100644
--- a/Src/Newtonsoft.Json/Converters/DataSetConverter.cs
+++ b/Src/Newtonsoft.Json/Converters/DataSetConverter.cs
@@ -33,7 +33,7 @@ namespace Newtonsoft.Json.Converters
///
/// Converts a to and from JSON.
///
- public class DataSetConverter : JsonConverter
+ public class DataSetConverter : JsonConverter
{
///
/// Writes the JSON representation of the object.
@@ -41,7 +41,7 @@ namespace Newtonsoft.Json.Converters
/// The to write to.
/// The value.
/// The calling serializer.
- public override void WriteJson(JsonWriter writer, DataSet value, JsonSerializer serializer)
+ public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value == null)
{
@@ -49,13 +49,14 @@ namespace Newtonsoft.Json.Converters
return;
}
+ DataSet dataSet = (DataSet)value;
DefaultContractResolver resolver = serializer.ContractResolver as DefaultContractResolver;
DataTableConverter converter = new DataTableConverter();
writer.WriteStartObject();
- foreach (DataTable table in value.Tables)
+ foreach (DataTable table in dataSet.Tables)
{
writer.WritePropertyName((resolver != null) ? resolver.GetResolvedPropertyName(table.TableName) : table.TableName);
@@ -70,11 +71,10 @@ namespace Newtonsoft.Json.Converters
///
/// The to read from.
/// Type of the object.
- /// The existing value of object being read. If there is no existing value then null will be used.
- /// The existing value has a value.
+ /// The existing value of object being read.
/// The calling serializer.
/// The object value.
- public override DataSet ReadJson(JsonReader reader, Type objectType, DataSet existingValue, bool hasExistingValue, JsonSerializer serializer)
+ public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
@@ -107,6 +107,18 @@ namespace Newtonsoft.Json.Converters
return ds;
}
+
+ ///
+ /// Determines whether this instance can convert the specified value type.
+ ///
+ /// Type of the value.
+ ///
+ /// true if this instance can convert the specified value type; otherwise, false.
+ ///
+ public override bool CanConvert(Type valueType)
+ {
+ return typeof(DataSet).IsAssignableFrom(valueType);
+ }
}
}
diff --git a/Src/Newtonsoft.Json/Converters/DataTableConverter.cs b/Src/Newtonsoft.Json/Converters/DataTableConverter.cs
index b49afe77..ffb7af01 100644
--- a/Src/Newtonsoft.Json/Converters/DataTableConverter.cs
+++ b/Src/Newtonsoft.Json/Converters/DataTableConverter.cs
@@ -37,7 +37,7 @@ namespace Newtonsoft.Json.Converters
///
/// Converts a to and from JSON.
///
- public class DataTableConverter : JsonConverter
+ public class DataTableConverter : JsonConverter
{
///
/// Writes the JSON representation of the object.
@@ -45,7 +45,7 @@ namespace Newtonsoft.Json.Converters
/// The to write to.
/// The value.
/// The calling serializer.
- public override void WriteJson(JsonWriter writer, DataTable value, JsonSerializer serializer)
+ public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value == null)
{
@@ -53,11 +53,12 @@ namespace Newtonsoft.Json.Converters
return;
}
+ DataTable table = (DataTable)value;
DefaultContractResolver resolver = serializer.ContractResolver as DefaultContractResolver;
writer.WriteStartArray();
- foreach (DataRow row in value.Rows)
+ foreach (DataRow row in table.Rows)
{
writer.WriteStartObject();
foreach (DataColumn column in row.Table.Columns)
@@ -83,20 +84,19 @@ namespace Newtonsoft.Json.Converters
///
/// The to read from.
/// Type of the object.
- /// The existing value of object being read. If there is no existing value then null will be used.
- /// The existing value has a value.
+ /// The existing value of object being read.
/// The calling serializer.
/// The object value.
- public override DataTable ReadJson(JsonReader reader, Type objectType, DataTable existingValue, bool hasExistingValue, JsonSerializer serializer)
+ public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
return null;
}
- DataTable dt = existingValue;
+ DataTable dt = existingValue as DataTable;
- if (!hasExistingValue)
+ if (dt == null)
{
// handle typed datasets
dt = (objectType == typeof(DataTable))
@@ -237,6 +237,18 @@ namespace Newtonsoft.Json.Converters
throw JsonSerializationException.Create(reader, "Unexpected JSON token when reading DataTable: {0}".FormatWith(CultureInfo.InvariantCulture, tokenType));
}
}
+
+ ///
+ /// Determines whether this instance can convert the specified value type.
+ ///
+ /// Type of the value.
+ ///
+ /// true if this instance can convert the specified value type; otherwise, false.
+ ///
+ public override bool CanConvert(Type valueType)
+ {
+ return typeof(DataTable).IsAssignableFrom(valueType);
+ }
}
}
diff --git a/Src/Newtonsoft.Json/Converters/RegexConverter.cs b/Src/Newtonsoft.Json/Converters/RegexConverter.cs
index ed41299f..c63e6cce 100644
--- a/Src/Newtonsoft.Json/Converters/RegexConverter.cs
+++ b/Src/Newtonsoft.Json/Converters/RegexConverter.cs
@@ -48,6 +48,12 @@ namespace Newtonsoft.Json.Converters
/// The calling serializer.
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
+ if (value == null)
+ {
+ writer.WriteNull();
+ return;
+ }
+
Regex regex = (Regex)value;
#pragma warning disable 618
diff --git a/Src/Newtonsoft.Json/Converters/VersionConverter.cs b/Src/Newtonsoft.Json/Converters/VersionConverter.cs
index 32d2f12e..df52718f 100644
--- a/Src/Newtonsoft.Json/Converters/VersionConverter.cs
+++ b/Src/Newtonsoft.Json/Converters/VersionConverter.cs
@@ -32,7 +32,7 @@ namespace Newtonsoft.Json.Converters
///
/// Converts a to and from a string (e.g. "1.2.3.4").
///
- public class VersionConverter : JsonConverter
+ public class VersionConverter : JsonConverter
{
///
/// Writes the JSON representation of the object.
@@ -40,15 +40,20 @@ namespace Newtonsoft.Json.Converters
/// The to write to.
/// The value.
/// The calling serializer.
- public override void WriteJson(JsonWriter writer, Version value, JsonSerializer serializer)
+ public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value == null)
{
writer.WriteNull();
- return;
}
-
- writer.WriteValue(value.ToString());
+ else if (value is Version)
+ {
+ writer.WriteValue(value.ToString());
+ }
+ else
+ {
+ throw new JsonSerializationException("Expected Version object value");
+ }
}
///
@@ -56,11 +61,10 @@ namespace Newtonsoft.Json.Converters
///
/// The to read from.
/// Type of the object.
- /// The existing value of object being read. If there is no existing value then null will be used.
- /// The existing value has a value.
+ /// The existing property value of the JSON that is being converted.
/// The calling serializer.
/// The object value.
- public override Version ReadJson(JsonReader reader, Type objectType, Version existingValue, bool hasExistingValue, JsonSerializer serializer)
+ public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
@@ -86,5 +90,17 @@ namespace Newtonsoft.Json.Converters
}
}
}
+
+ ///
+ /// Determines whether this instance can convert the specified object type.
+ ///
+ /// Type of the object.
+ ///
+ /// true if this instance can convert the specified object type; otherwise, false.
+ ///
+ public override bool CanConvert(Type objectType)
+ {
+ return objectType == typeof(Version);
+ }
}
}
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs b/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs
index 0723c679..63f0a03c 100644
--- a/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs
+++ b/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs
@@ -1114,6 +1114,12 @@ namespace Newtonsoft.Json.Converters
/// The value.
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
+ if (value == null)
+ {
+ writer.WriteNull();
+ return;
+ }
+
IXmlNode node = WrapXml(value);
XmlNamespaceManager manager = new XmlNamespaceManager(new NameTable());