From cf1e58ae9bb6898e72736c1ba535899c06cd3aa5 Mon Sep 17 00:00:00 2001 From: SteveCollie Date: Mon, 21 Sep 2020 18:23:31 +0100 Subject: [PATCH 1/2] Improve handling a datetime field in a sub-type --- JsonSubTypes.Tests/DatesTests.cs | 34 ++++++++++++++++++++++++++++++++ JsonSubTypes/JsonSubtypes.cs | 5 +++++ 2 files changed, 39 insertions(+) create mode 100644 JsonSubTypes.Tests/DatesTests.cs diff --git a/JsonSubTypes.Tests/DatesTests.cs b/JsonSubTypes.Tests/DatesTests.cs new file mode 100644 index 0000000..beb4025 --- /dev/null +++ b/JsonSubTypes.Tests/DatesTests.cs @@ -0,0 +1,34 @@ +using System; +using Newtonsoft.Json; +using NUnit.Framework; + +namespace JsonSubTypes.Tests +{ + [TestFixture] + public class DatesTest + { + [JsonConverter(typeof(JsonSubtypes), nameof(SubTypeClass.Discriminator))] + public abstract class MainClass + { + } + + public class SubTypeClass : MainClass + { + public string Discriminator => "SubTypeClass"; + + public DateTimeOffset? Date { get; set; } + } + + [Test] + public void DeserializingSubTypeWithDateParsesCorrectly() + { + var json = "{ \"Discriminator\": \"MainClass\", \"Date\": \"2020-06-28T00:00:00.00000+00:00\" }"; + + var obj = JsonConvert.DeserializeObject(json); + + Assert.That(obj, Is.Not.Null); + Assert.That(obj.Date.HasValue, Is.True); + Assert.That(obj.Date.Value.Offset, Is.EqualTo(TimeSpan.Zero)); + } + } +} diff --git a/JsonSubTypes/JsonSubtypes.cs b/JsonSubTypes/JsonSubtypes.cs index 296d302..c4f6cec 100644 --- a/JsonSubTypes/JsonSubtypes.cs +++ b/JsonSubTypes/JsonSubtypes.cs @@ -201,7 +201,12 @@ private static Type GetElementType(Type arrayOrGenericContainer) private object ReadObject(JsonReader reader, Type objectType, JsonSerializer serializer) { + // I would prefer to create a new reader, but can't work out how to + // This seems a reasonable alternative - https://github.com/JamesNK/Newtonsoft.Json/issues/1605#issuecomment-602673364 + var savedDateParseSettings = reader.DateParseHandling; + reader.DateParseHandling = DateParseHandling.None; var jObject = JObject.Load(reader); + reader.DateParseHandling = savedDateParseSettings; var targetType = GetType(jObject, objectType, serializer) ?? objectType; From 2b754700aa3e675f23638cc8e57a5f02cf06ff67 Mon Sep 17 00:00:00 2001 From: Emmanuel Counasse Date: Wed, 23 Sep 2020 23:54:07 +0200 Subject: [PATCH 2/2] Update DatesTests.cs Update test to use JsonSubtypes converter --- JsonSubTypes.Tests/DatesTests.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/JsonSubTypes.Tests/DatesTests.cs b/JsonSubTypes.Tests/DatesTests.cs index beb4025..65c6c35 100644 --- a/JsonSubTypes.Tests/DatesTests.cs +++ b/JsonSubTypes.Tests/DatesTests.cs @@ -8,6 +8,7 @@ namespace JsonSubTypes.Tests public class DatesTest { [JsonConverter(typeof(JsonSubtypes), nameof(SubTypeClass.Discriminator))] + [JsonSubtypes.KnownSubType(typeof(SubTypeClass), "SubTypeClass")] public abstract class MainClass { } @@ -22,13 +23,14 @@ public class SubTypeClass : MainClass [Test] public void DeserializingSubTypeWithDateParsesCorrectly() { - var json = "{ \"Discriminator\": \"MainClass\", \"Date\": \"2020-06-28T00:00:00.00000+00:00\" }"; + var json = "{ \"Discriminator\": \"SubTypeClass\", \"Date\": \"2020-06-28T00:00:00.00000+00:00\" }"; - var obj = JsonConvert.DeserializeObject(json); + var obj = JsonConvert.DeserializeObject(json); Assert.That(obj, Is.Not.Null); - Assert.That(obj.Date.HasValue, Is.True); - Assert.That(obj.Date.Value.Offset, Is.EqualTo(TimeSpan.Zero)); + Assert.That(obj, Is.InstanceOf()); + Assert.That(((SubTypeClass)obj).Date.HasValue, Is.True); + Assert.That(((SubTypeClass)obj).Date.Value.Offset, Is.EqualTo(TimeSpan.Zero)); } } }