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.
DateParseHandling.None
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; }
}
}
}
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
.
I had a similar problem and solved it with
JToken rootObj = JsonConvert.DeserializeObject<dynamic>(myJsonString, new JsonSerializerSettings { DateParseHandling = DateParseHandling.None }) as JToken;
As others wrote, once you have the JObject
/ JToken
it is already too late for the DateParseHandling
, and the DateParseHandling
is not available for the JToken.Parse()
.
JToken rootObj = JsonConvert.DeserializeObject<dynamic>(myJsonString, new JsonSerializerSettings { DateParseHandling = DateParseHandling.None }) as JToken;
if (rootObj.Children<JProperty>().Count() != 1) Console.WriteLine($"Error: json no or multiple root tokens");
JProperty rootProp = rootObj.Children<JProperty>().First(); // with the property you can access the name if needed
if (rootProp.Name.Equals("theTokenNameIAmLookingFor"))
{
Console.WriteLine($"found my token name: {rootProp.Name}");
MyClass myObj = rootObj.ToObject<MyClass>();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With