Newtonsoft.Json.Linq.JObject.ToObject() 以字符串格式转换日期
Posted
技术标签:
【中文标题】Newtonsoft.Json.Linq.JObject.ToObject() 以字符串格式转换日期【英文标题】:Newtonsoft.Json.Linq.JObject.ToObject() converting date in string format 【发布时间】:2018-06-14 13:00:42 【问题描述】:我正在构建一个 .net 核心库。该错误适用于 1.1 和 2.0。
我有一个JObject
(我阅读了许多其他答案,人们告诉 OP 只做JsonConvert.Deserialize(obj)
,这不是一个选项,我需要它)。
JObject
在字符串中有一个日期,我将把它反序列化为一个也有它作为字符串的对象,并且我需要它的格式与提供的相同。
一个answer 我看到声称一旦对象变为JObject
,日期就会被解析为该格式,但我发现事实并非如此,.ToObject()
是实际发生这种转换的地方。
我在这里搜索了很多,发现了一些对我不起作用的公认解决方案。
-
Setting
DateParseHandling.None
Explicitly specifying the date format.(tried the other approach in this answer as well)
这些都不起作用。
测试代码:
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;
【问题讨论】:
有什么理由不使用innerThing = JsonConvert.DeserializeObject<InnerThing>(thing.Data.ToString());
?
【参考方案1】:
您一直在尝试序列化数据,但是当您反序列化 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
。
【讨论】:
【参考方案2】:我遇到了类似的问题,解决了
JToken rootObj = JsonConvert.DeserializeObject<dynamic>(myJsonString, new JsonSerializerSettings DateParseHandling = DateParseHandling.None ) as JToken;
正如其他人所写,一旦您拥有JObject
/ JToken
,对于DateParseHandling
已经为时已晚,并且DateParseHandling
不适用于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>();
【讨论】:
以上是关于Newtonsoft.Json.Linq.JObject.ToObject() 以字符串格式转换日期的主要内容,如果未能解决你的问题,请参考以下文章