Newtonsoft.Json.Linq.JObject.ToObject()以字符串格式转换日期

时间:2018-01-04 18:22:19

标签: c# json date .net-core

我正在构建.net核心库。对于1.1和2.0,错误都是正确的。

我有一个JObject(我读了一堆其他答案,人们告诉OP只做JsonConvert.Deserialize(obj),这不是一个选项,我需要它。)< / p>

JObject在字符串中有一个日期,并且我要将它反序列化为一个也将它作为字符串的对象,我需要使用与它相同的格式提供。

一个answer我看到声称对象变为JObject后,日期会被解析为该格式,但我发现情况并非如此.ToObject()是转换实际发生的地方。

我在这里搜索了很多,发现了一些对我不起作用的公认解决方案。

  1. Setting DateParseHandling.None
  2. Explicitly specifying the date format.(tried the other approach in this answer as well)
  3. 这些都没有奏效。

    测试代码:

    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; }
            }
        }
    }
    

2 个答案:

答案 0 :(得分:7)

您在序列化数据时一直在进行实验,但是当您反序列化 JSON时,转换就会发生。这就是您需要禁用DateParseHandling的地方。以下是您需要的更改:

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

新输出:

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

您可以通过这种方式看到JObject的差异:

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

在指定设置之前,会打印Date。使用防止日期解析的设置,将打印String

答案 1 :(得分:0)

我遇到了类似的问题,并用

解决了它

JToken rootObj = JsonConvert.DeserializeObject<dynamic>(myJsonString, new JsonSerializerSettings { DateParseHandling = DateParseHandling.None }) as JToken;

正如其他人所写,一旦您拥有 JObject / JTokenDateParseHandling 已经太晚了,DateParseHandling 不适用于 {{1 }}。

JToken.Parse()