diff --git a/Src/Newtonsoft.Json/Converters/BsonObjectIdConverter.cs b/Src/Newtonsoft.Json/Converters/BsonObjectIdConverter.cs
index 533e113d..c2da6c3a 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,18 +42,16 @@ namespace Newtonsoft.Json.Converters
/// The to write to.
/// The value.
/// The calling serializer.
- public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+ public override void WriteJson(JsonWriter writer, BsonObjectId value, JsonSerializer serializer)
{
- BsonObjectId objectId = (BsonObjectId)value;
-
BsonWriter bsonWriter = writer as BsonWriter;
if (bsonWriter != null)
{
- bsonWriter.WriteObjectId(objectId.Value);
+ bsonWriter.WriteObjectId(value.Value);
}
else
{
- writer.WriteValue(objectId.Value);
+ writer.WriteValue(value.Value);
}
}
@@ -62,10 +60,11 @@ namespace Newtonsoft.Json.Converters
///
/// The to read from.
/// Type of the object.
+ /// The existing value has a value.
/// The existing value of object being read.
/// The calling serializer.
/// The object value.
- public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+ public override BsonObjectId ReadJson(JsonReader reader, Type objectType, bool existingHasValue, BsonObjectId existingValue, JsonSerializer serializer)
{
if (reader.TokenType != JsonToken.Bytes)
{
@@ -76,17 +75,5 @@ 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 f75d7e55..c7a436f6 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,16 +41,15 @@ namespace Newtonsoft.Json.Converters
/// The to write to.
/// The value.
/// The calling serializer.
- public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+ public override void WriteJson(JsonWriter writer, DataSet value, JsonSerializer serializer)
{
- DataSet dataSet = (DataSet)value;
DefaultContractResolver resolver = serializer.ContractResolver as DefaultContractResolver;
DataTableConverter converter = new DataTableConverter();
writer.WriteStartObject();
- foreach (DataTable table in dataSet.Tables)
+ foreach (DataTable table in value.Tables)
{
writer.WritePropertyName((resolver != null) ? resolver.GetResolvedPropertyName(table.TableName) : table.TableName);
@@ -65,10 +64,11 @@ namespace Newtonsoft.Json.Converters
///
/// The to read from.
/// Type of the object.
+ /// The existing value has a value.
/// The existing value of object being read.
/// The calling serializer.
/// The object value.
- public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+ public override DataSet ReadJson(JsonReader reader, Type objectType, bool existingHasValue, DataSet existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
@@ -101,18 +101,6 @@ 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 7046c292..faba9420 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,14 +45,13 @@ namespace Newtonsoft.Json.Converters
/// The to write to.
/// The value.
/// The calling serializer.
- public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+ public override void WriteJson(JsonWriter writer, DataTable value, JsonSerializer serializer)
{
- DataTable table = (DataTable)value;
DefaultContractResolver resolver = serializer.ContractResolver as DefaultContractResolver;
writer.WriteStartArray();
- foreach (DataRow row in table.Rows)
+ foreach (DataRow row in value.Rows)
{
writer.WriteStartObject();
foreach (DataColumn column in row.Table.Columns)
@@ -78,19 +77,20 @@ namespace Newtonsoft.Json.Converters
///
/// The to read from.
/// Type of the object.
+ /// The existing value has a value.
/// The existing value of object being read.
/// The calling serializer.
/// The object value.
- public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+ public override DataTable ReadJson(JsonReader reader, Type objectType, bool existingHasValue, DataTable existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
return null;
}
- DataTable dt = existingValue as DataTable;
+ DataTable dt = existingValue;
- if (dt == null)
+ if (!existingHasValue)
{
// handle typed datasets
dt = (objectType == typeof(DataTable))
@@ -231,18 +231,6 @@ 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/VersionConverter.cs b/Src/Newtonsoft.Json/Converters/VersionConverter.cs
index df52718f..575f4b59 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,20 +40,13 @@ namespace Newtonsoft.Json.Converters
/// The to write to.
/// The value.
/// The calling serializer.
- public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+ public override void WriteJson(JsonWriter writer, Version value, JsonSerializer serializer)
{
if (value == null)
{
writer.WriteNull();
}
- else if (value is Version)
- {
- writer.WriteValue(value.ToString());
- }
- else
- {
- throw new JsonSerializationException("Expected Version object value");
- }
+ writer.WriteValue(value.ToString());
}
///
@@ -61,10 +54,11 @@ namespace Newtonsoft.Json.Converters
///
/// The to read from.
/// Type of the object.
+ /// 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 object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+ public override Version ReadJson(JsonReader reader, Type objectType, bool existingHasValue, Version existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
@@ -90,17 +84,5 @@ 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/JsonConverter.cs b/Src/Newtonsoft.Json/JsonConverter.cs
index 3f04f620..245ca4a6 100644
--- a/Src/Newtonsoft.Json/JsonConverter.cs
+++ b/Src/Newtonsoft.Json/JsonConverter.cs
@@ -28,6 +28,7 @@ using System.Collections.Generic;
using System.Text;
using Newtonsoft.Json.Utilities;
using Newtonsoft.Json.Schema;
+using System.Globalization;
namespace Newtonsoft.Json
{
@@ -81,4 +82,75 @@ namespace Newtonsoft.Json
get { return true; }
}
}
+
+ ///
+ /// Converts an object to and from JSON.
+ ///
+ ///
+ public abstract class JsonConverter : JsonConverter
+ {
+ ///
+ /// Writes the JSON representation of the object.
+ ///
+ /// The to write to.
+ /// The value.
+ /// The calling serializer.
+ public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+ {
+ if (!(value != null ? value is T : ReflectionUtils.IsNullable(typeof(T))))
+ {
+ throw new JsonSerializationException("This converter cannot convert {0} of type {1}".FormatWith(CultureInfo.InvariantCulture, value, value?.GetType()));
+ }
+ WriteJson(writer, (T)value, serializer);
+ }
+
+ ///
+ /// Writes the JSON representation of the object.
+ ///
+ /// The to write to.
+ /// The value.
+ /// The calling serializer.
+ public abstract void WriteJson(JsonWriter writer, T value, JsonSerializer serializer);
+
+ ///
+ /// Reads the JSON representation of the object.
+ ///
+ /// The to read from.
+ /// Type of the object.
+ /// The existing value of object being read.
+ /// The calling serializer.
+ /// The object value.
+ public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+ {
+ var existingIsNull = existingValue == null;
+ if (!(existingIsNull || existingValue is T))
+ {
+ throw new JsonSerializationException("This converter cannot convert {0} of type {1}".FormatWith(CultureInfo.InvariantCulture, existingValue, existingValue.GetType()));
+ }
+ return ReadJson(reader, objectType, !existingIsNull, existingIsNull ? default(T) : (T)existingValue, serializer);
+ }
+
+ ///
+ /// Reads the JSON representation of the object.
+ ///
+ /// The to read from.
+ /// Type of the object.
+ /// The existing value has a value.
+ /// The existing value of object being read.
+ /// The calling serializer.
+ /// The object value.
+ public abstract T ReadJson(JsonReader reader, Type objectType, bool existingHasValue, T existingValue, JsonSerializer serializer);
+
+ ///
+ /// 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 typeof(T).IsAssignableFrom(objectType);
+ }
+ }
}
\ No newline at end of file