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

LLL*_*LLL 2 c# json date .net-core

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

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

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

我看到的一个答案声称,只要对象成为JObject日期,就会将其解析为该格式,但我发现情况并非如此,.ToObject()而且这种转换实际上正在发生.

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

  1. 设置 DateParseHandling.None
  2. 明确指定日期格式.(在此答案中尝试了其他方法)

这些都没有奏效.

测试代码:

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; }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 7

您在序列化数据时一直在进行实验,但是在您开始反序列化JSON 时会发生转换.那是你需要禁用的地方DateParseHandling.这是您需要的变化:

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

新产出:

"CreatedAt": "2018-01-04T14:48:39.7472110Z"
2018-01-04T14:48:39.7472110Z
True
2018-01-04T14:48:39.7472110Z
True
Run Code Online (Sandbox Code Playgroud)

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

var property = (JProperty) thing.Data.First;
var value = (JValue) property.Value;
Console.WriteLine(value.Type);
Run Code Online (Sandbox Code Playgroud)

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