反序列化Json对象 – DateTime

我的web-api返回一个用户对象。 在该对象中有一个DateTime属性。 当我在我的应用程序中读取它时,我得到一个错误,因为代表DateTime的字符串无效,它缺少\Date ...

{System.Runtime.Serialization.SerializationException:反序列化User类型的对象时出错。 DateTime内容’1984-10-02T01:00:00’不以’/ Date(’和以’)/’开头,如JSON所需。 —>

 public static async Task GetUser(string email) { try { using (HttpClient client = new HttpClient()) { HttpResponseMessage response = await client.GetAsync(url + "?email="+email); if (response.IsSuccessStatusCode) { string content = await response.Content.ReadAsStringAsync(); User user = DataService.Deserialize(content); return user; } return null; } } catch (Exception ex) { return null; } } 

这是我用来反序列化的方法。

 public static T Deserialize(string json) { try { var _Bytes = Encoding.Unicode.GetBytes(json); using (MemoryStream _Stream = new MemoryStream(_Bytes)) { var _Serializer = new DataContractJsonSerializer(typeof(T)); return (T)_Serializer.ReadObject(_Stream); } } catch (Exception ex) { throw ex; } } 

要解决这个问题,可能最简单的方法是将DataContract类型的值类型设置为“string”。 然后,如果您需要使用.NET日期时间,则需要对字符串值执行DateTime.Parse。 这将消除您的反序列化问题。 序列化的原始类可能使用字符串值开头,因为它缺少日期所需的格式。

请注意,当您执行DateTime.Parse时,如果存在时区信息,它会将其转换为您计算机的本地时间(这是愚蠢的,我知道)。 仅供参考。

在JSON规范中没有用于交换日期的标准格式 ,这就是为什么JSON中存在许多不同的异构日期格式的原因!

DataContractJsonSerializer以自1970年以来计数msecs的格式序列化日期,由Date()包围,如下所示: Date(1335205592410)并期望相同的格式反序列化回DateTime 。 但是,作为JSON日期字符串获得的是ISO8601格式,这是当今大多数浏览器/软件用于序列化日期的格式!

JavaScriptSerializer是.Net中的另一种JSON序列化程序,它几乎可以序列化任何类型,包括与JSON字符串或来自JSON字符串的匿名类型,并且它能够以ISO8601格式或DataContractJsonSerializer提供的格式反序列化JSON日期。

使用JavaScriptSerializer ,您的Deserialize方法将如下所示:

 public static T Deserialize(string json) { return new JavaScriptSerializer().Deserialize(json); } 

我在添加包Json.net(Newtonsoft.Json)时发现了如何修复它。

 public async static Task Deserialize(string json) { var value = await Newtonsoft.Json.JsonConvert.DeserializeObjectAsync(json); return value; } 

可能是DateTime实际上是以“可空”的forms回归,比如“DateTime?” (带问号)?

因为那时它可能是NULL,因为和“.HasValue == false”。

只猜这里… 🙂

只需更改DataContractJsonSerializer上的DateTimeFormat,如下所示:

  public static T Deserialize(string json) { try { var settings = new DataContractJsonSerializerSettings { DateTimeFormat = new System.Runtime.Serialization.DateTimeFormat("o") }; var _Bytes = Encoding.Unicode.GetBytes(json); using (MemoryStream _Stream = new MemoryStream(_Bytes)) { var _Serializer = new DataContractJsonSerializer(typeof(T), settings); return (T)_Serializer.ReadObject(_Stream); } } catch (Exception ex) { throw ex; } }