2017-06-16 115 views
1

我想反序列化一个JSON字符串/对象和JSON对象包含一些日期时间字段。JSON反序列化的日期时间,直到毫秒在C#

我的函数来反序列化JSON对象是 -

public static T ParseJSONToObject<T>(string entity) 
{ 

    return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(entity, new IsoDateTimeConverter{ 
      DateTimeFormat = "yyyy-MM-dd'T'HH:mm:ss.fffffff"        
     }); 

} 

我想要的日期 - 时间域应该转换至毫秒,如果以毫秒为单位没有价值,那么它应该显示为零的,直到7位数字。下面是我的JSON对象 -

[ 
    {"Key": "PendingDate", "Value": "2017-06-15T13:58:00"}, 
    {"Key": "OwnerId", "Value": "xyz"}, 
    {"Key": "ProductList", "Value": "0"}, 
    {"Key": "CreatedDate", "Value": "2017-06-16T09:11:21.678544"}, 
    {"Key": "ModifiedDate", "Value": "2017-06-16T09:11:21.678544"} 
] 

但是当我通过这个对象到我的JSON解析器函数它不是我想要的格式返回日期时间值。

但是当我使用下面的代码来反序列化一个JSON字符串它给正确的输出 -

  var json = "{\"timestamp\":\"2017-06-15T13:58:00.000\"}"; 
      var dict = JsonConvert.DeserializeObject<Dictionary<string,  object>>(json); 
      var r = ((DateTime)dict["timestamp"]).ToString("O"); 

并且输出为─

2017-06-15T13:58:00.0000000 

这是我所需要的输出但我不知道我需要如何用我的JSON解析器函数实现 。

+0

你有字典的数组,而不是一个单一的字典。另外,'DateTime'类型根本没有格式。它是一个像“int”和“double”这样的二进制值。您的*代码*虽然,将日期转换为*字符串*。毕竟这是什么问题? –

+0

实际显示问题的邮政编码。您发布的内容表明您将某些(不存在的)DateTime格式的字符串表示混淆了。 BTW ISO8601是JSON.NET的默认设置。你不需要指定它 –

回答

0

无需指定DateTimeFormat,因为默认格式的读数为毫秒。在对象到DateTime转换期间,您将失去毫秒。尝试将内容解析为动态类型而不是对象类型,以避免编译器需要进行转换。

更新:删除foreach循环显示值。

/// <summary> 
    /// Specifies the settings on a <see cref="T:Newtonsoft.Json.JsonSerializer" /> object. 
    /// </summary> 
    public class JsonSerializerSettings 
    { 
    ... 
    internal const string DefaultDateFormatString = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK"; 

示例代码

var data = "[{\"Key\": \"PendingDate\", \"Value\": \"2017-06-15T13:58:00\"}, {\"Key\": \"OwnerId\", \"Value\": \"xyz\"}, {\"Key\": \"ProductList\", \"Value\": \"0\"}, {\"Key\": \"CreatedDate\", \"Value\": \"2017-06-16T09:11:21.678544\"}, {\"Key\": \"ModifiedDate\", \"Value\": \"2017-06-16T09:11:21.678544\"}]"; 

    var deserilizedData = Newtonsoft.Json.JsonConvert.DeserializeObject<OrderDetail[]>(data); 

    var order = deserilizedData.ToDictionary(r => r.Key, r => r.Value); 

    Console.WriteLine("PendingDate: " + order["PendingDate"].ToString("o")); 
    Console.WriteLine("OwnerId: " + order["OwnerId"].ToString()); 
    Console.WriteLine("ProductList: " + order["ProductList"].ToString()); 
    Console.WriteLine("CreatedDate: " + order["CreatedDate"].ToString("o")); 
    Console.WriteLine("ModifiedDate: " + order["ModifiedDate"].ToString("o")); 

输出

PendingDate: 2017-06-15T13:58:00.0000000 
OwnerId: xyz 
ProductList: 0 
CreatedDate: 2017-06-16T09:11:21.6785440 
ModifiedDate: 2017-06-16T09:11:21.6785440 

实体反序列化

public class OrderDetail 
{ 
    public string Key { get; set; } 

    public dynamic Value { get; set; } 
} 
+0

嗨Kaushal ...感谢您的回复,但我不想在这种情况下使用循环。我需要一个不使用任何循环的直接解决方案。 – user3848036

+0

@ user3848036循环只是为了显示值。我想说的是DeserializeObject将解析并保留毫秒。从对象类型转换时可能会丢失它们。请分享你如何使用解析值的代码。要验证它确实保留了值,可以将断点放在返回值上并交叉检查毫秒属性 – Kaushal

0

尝试作出这样的。

class Test 
{ 
    public string Key { get; set; } 
    public string Value { get; set; } 
} 

-

DateTime dtParse; 

var deserializeJson = (from d in JsonConvert.DeserializeObject<Test[]>(entity) 
         select new Test() 
         { 
          Key = d.Key, 
          Value = DateTime.TryParse(d.Value, out dtParse) == true ? Convert.ToDateTime(d.Value).ToString("yyyy-MM-ddTHH:mm:ss.fffffff") : d.Value 
         }).ToList(); 
+0

我简化了答案,我相信这是您正在寻找的。 –

+0

@log感谢您的回复。但是,您能否以“IsoDateTimeConverter”的方式提出任何建议,因为我无法硬编码您在代码中执行的属性名称。因为我有一个全局函数可用于任何对象和任何Datetime类型的属性名称。 – user3848036

+0

我真的尝试过使用'IsoDateTimeConverter',但没有成功,我创建了替代解决方案,看看并告诉我你的想法 –