Newtonsoft.Json.Linq.JObject.ToObject() converting date in string format

I'm building a .net core library. The error is true for 1.1 as well as 2.0.

I have a JObject (I read a bunch of other answers where people tell the OP to just do JsonConvert.Deserialize(obj), that's not an option, I need to have it).

That JObject has a date in a string, and I'm going to deserialize it to an object that also has it as a string, and I need to have it in the same format as it is provided.

One answer I saw claims that as soon the object becomes a JObject the date is parsed to that format, but I found that that's not the case and .ToObject() is where this conversion is actually happening.

I searched a lot on here and found a couple of accepted solutions that do not work for me.

  1. Setting DateParseHandling.None
  2. Explicitly specifying the date format.(tried the other approach in this answer as well)

None of those worked.

Testing code:

using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace JobjectDateTest
{
    class Program
    {
        static void Main(string[] args)
        {
            var json = @"{""Data"": {""CreatedAt"":""2018-01-04T14:48:39.7472110Z""}}";
            var thing = JsonConvert.DeserializeObject<Thing>(json);
            Console.WriteLine(thing.Data.First); // "CreatedAt": "2018-01-04T14:48:39.747211Z"

            var jsonSer = new JsonSerializer { DateFormatString = "yyyy-MM-ddTHH:mm:ssZ" };
            var innerThing = thing.Data.ToObject<InnerThing>(jsonSer);

            Console.WriteLine(innerThing.CreatedAt); // 01/04/2018 14:48:39
            Console.WriteLine(innerThing.CreatedAt == "2018-01-04T14:48:39.7472110Z"); // false

            jsonSer = new JsonSerializer { DateParseHandling = DateParseHandling.None };
            innerThing = thing.Data.ToObject<InnerThing>(jsonSer);

            Console.WriteLine(innerThing.CreatedAt); // 01/04/2018 14:48:39
            Console.WriteLine(innerThing.CreatedAt == "2018-01-04T14:48:39.7472110Z"); // false
        }

        class Thing
        {
            public JObject Data { get; set; }
        }

        class InnerThing
        {
            public string CreatedAt { get; set; }
        }
    }
}
Jon Skeet
people
quotationmark

You've been experimenting when serializing the data, but the conversion is happening when you deserialize the JSON to start with. That's where you need to disable DateParseHandling. Here's the change you need:

var settings = new JsonSerializerSettings { DateParseHandling = DateParseHandling.None };
var thing = JsonConvert.DeserializeObject<Thing>(json, settings);

New output:

"CreatedAt": "2018-01-04T14:48:39.7472110Z"
2018-01-04T14:48:39.7472110Z
True
2018-01-04T14:48:39.7472110Z
True

You can see the difference in the JObject this way:

var property = (JProperty) thing.Data.First;
var value = (JValue) property.Value;
Console.WriteLine(value.Type);

Before specifying the settings, this prints Date. With the settings preventing date parsing, this prints String.

people

See more on this question at Stackoverflow