From fa85ebfbbfe7ba1ace77e5d17dafe92d47ee76e6 Mon Sep 17 00:00:00 2001 From: JamesNK Date: Thu, 28 Jan 2010 07:20:01 +0000 Subject: [PATCH] -Fix passed in JsonConverter not overriding internally specified JsonConverter --- .../Converters/DataTableConverterTests.cs | 34 +++++++++++++++++++ .../Serialization/DefaultContractResolver.cs | 14 ++++---- .../Serialization/JsonContract.cs | 4 +++ .../JsonSerializerInternalReader.cs | 7 ++++ .../JsonSerializerInternalWriter.cs | 3 +- 5 files changed, 53 insertions(+), 9 deletions(-) diff --git a/Src/Newtonsoft.Json.Tests/Converters/DataTableConverterTests.cs b/Src/Newtonsoft.Json.Tests/Converters/DataTableConverterTests.cs index 1790c689..e0b1f2fb 100644 --- a/Src/Newtonsoft.Json.Tests/Converters/DataTableConverterTests.cs +++ b/Src/Newtonsoft.Json.Tests/Converters/DataTableConverterTests.cs @@ -102,6 +102,40 @@ namespace Newtonsoft.Json.Tests.Converters } ]", json); } + + public class TestDataTableConverter : JsonConverter + { + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + DataTable d = (DataTable) value; + writer.WriteValue(d.TableName); + } + + public override object ReadJson(JsonReader reader, Type objectType, JsonSerializer serializer) + { + //reader.Read(); + DataTable d = new DataTable((string)reader.Value); + + return d; + } + + public override bool CanConvert(Type objectType) + { + return (objectType == typeof (DataTable)); + } + } + + [Test] + public void PassedInJsonConverterOverridesInternalConverter() + { + DataTable t1 = new DataTable("Custom"); + + string json = JsonConvert.SerializeObject(t1, Formatting.Indented, new TestDataTableConverter()); + Assert.AreEqual(@"""Custom""", json); + + DataTable t2 = JsonConvert.DeserializeObject(json, new TestDataTableConverter()); + Assert.AreEqual(t1.TableName, t2.TableName); + } } } #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs index caa5f07c..efd251e2 100644 --- a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs +++ b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs @@ -181,14 +181,7 @@ namespace Newtonsoft.Json.Serialization /// protected virtual JsonConverter ResolveContractConverter(Type objectType) { - // check for an attribute first - JsonConverter converter = JsonTypeReflector.GetJsonConverter(objectType, objectType); - if (converter != null) - return converter; - - // then see whether object is compadible with any of the built in converters - JsonSerializer.HasMatchingConverter(BuiltInConverters, objectType, out converter); - return converter; + return JsonTypeReflector.GetJsonConverter(objectType, objectType); } private void InitializeContract(JsonContract contract) @@ -210,6 +203,11 @@ namespace Newtonsoft.Json.Serialization contract.Converter = ResolveContractConverter(contract.UnderlyingType); + // then see whether object is compadible with any of the built in converters + JsonConverter internalConverter; + if (JsonSerializer.HasMatchingConverter(BuiltInConverters, contract.UnderlyingType, out internalConverter)) + contract.InternalConverter = internalConverter; + if (ReflectionUtils.HasDefaultConstructor(contract.CreatedType, true) || contract.CreatedType.IsValueType) { diff --git a/Src/Newtonsoft.Json/Serialization/JsonContract.cs b/Src/Newtonsoft.Json/Serialization/JsonContract.cs index fb78f1e3..482b3486 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonContract.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonContract.cs @@ -59,6 +59,10 @@ namespace Newtonsoft.Json.Serialization /// The converter. public JsonConverter Converter { get; set; } + // internally specified JsonConverter's to override default behavour + // checked for after passed in converters and attribute specified converters + internal JsonConverter InternalConverter { get; set; } + #if !PocketPC /// /// Gets or sets the method called immediately after deserialization of the object. diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs index fca5b071..47b4038f 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs @@ -168,15 +168,22 @@ namespace Newtonsoft.Json.Serialization { JsonConverter converter; + // member attribute converter if (memberConverter != null) return memberConverter.ReadJson(reader, objectType, GetInternalSerializer()); + // class attribute converter if (contract != null && contract.Converter != null) return contract.Converter.ReadJson(reader, objectType, GetInternalSerializer()); + // passed in converters if (objectType != null && Serializer.HasMatchingConverter(objectType, out converter)) return converter.ReadJson(reader, objectType, GetInternalSerializer()); + // internally specified converter + if (contract != null && contract.InternalConverter != null) + return contract.InternalConverter.ReadJson(reader, objectType, GetInternalSerializer()); + if (contract is JsonLinqContract) return CreateJToken(reader, contract); diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs index 1ca0daa4..4468b785 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs @@ -92,7 +92,8 @@ namespace Newtonsoft.Json.Serialization if (converter != null || ((converter = contract.Converter) != null) - || Serializer.HasMatchingConverter(contract.UnderlyingType, out converter)) + || Serializer.HasMatchingConverter(contract.UnderlyingType, out converter) + || ((converter = contract.InternalConverter) != null)) { SerializeConvertable(writer, converter, value, contract); }