2014-01-10 40 views
7

我試圖用Json.NET序列化一些野田時間值並遇到麻煩。序列化足夠簡單:用JSON.NET反序列化野田時間的LocalDateTime

LocalDateTime dt = ... // Assigned elsewhere 
LocalDateTimePattern isoDateTimePattern = LocalDateTimePattern.GeneralIsoPattern; 
JObject root = new JObject(); 
root.Add("time", isoDateTimePattern.Format(dt)); 

// Serialize other elements 

using (var sw = new StreamWriter(stream)) { 
    serializer.Serialize(sw, root); 
} 

但是反序列化是有問題的。 Json.NET似乎從 以上識別ISO格式的日期和時間,並自動將其轉換爲DateTime對象,這不是我想要的。

using (var sr = new StreamReader(stream)) { 
     using (var jr = new JsonTextReader(sr)) { 
      var root = serializer.Deserialize<JObject>(jr); 

      // Deserialize other elements 

      var time = root.GetValue("time"); // time.Type is JTokenType.Date 
      string timeStr = time.Value<string>(); // Is "01/10/2014 10:37:32" 

      // Kaboom. String is not in the right format (see above comment) 
      var parsedTime = isoDateTimePattern.Parse(time.Value<string>()); 
     } 
} 

從這個timeStr出來作爲美國格式的日期和時間,事實上,我猜想,time.Value<string>() 只是對Json.NET已經解析了一些內部DateTime對象調用ToString。 我可以做類似

var cdt = time.Value<DateTime>(); 
LocalDateTime ldt = new LocalDateTime(cdt.Year, cdt.Month, cdt.Day, cdt.Hour, cdt.Minute); 

但是這是令人費解和手段Json.NET正在執行不必要的轉換。

有什麼方法可以獲取JSON值的原始字符串值嗎?

回答

12

NuGet上有一個NodaTime.Serialization.JsonNet package,它似乎完全針對這種情況。下面是如何設置它:

下載並在您的解決方案安裝包後,以下using語句添加到您的代碼:

using NodaTime.Serialization.JsonNet; 

設置你的串行這樣的:

JsonSerializer serializer = new JsonSerializer(); 
serializer.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb); 

然後,當你反序列化,你可以使用ToObject<LocalDateTime>(serializer)這樣獲得從JObject一個LocalDateTime

using (var sr = new StreamReader(stream)) 
{ 
    using (var jr = new JsonTextReader(sr)) 
    { 
     var root = serializer.Deserialize<JObject>(jr); 

     // Deserialize other elements 

     var time = root.GetValue("time"); 
     var parsedTime = time.ToObject<LocalDateTime>(serializer); 
    } 
} 
+0

這看起來正是我想要的。謝謝! –

+0

同樣,你會如何序列化?在你的例子中,它看起來像你會使用以下,但它失敗,錯誤「測試方法LiveSerialTests.LinkTests.SerialSnapshotToJSONTest拋出異常:System.ArgumentException:對象序列化爲字符串。JObject實例預期。」:'根。添加(「time」,JObject.FromObject(time,serializer));' –

+1

使用'JToken.FromObject(time,serializer)',而不是'JObject.FromObject(time,serializer)'。前者將轉換爲任何類型的JToken(在這種情況下是一個包​​含字符串的JValue)。後者希望轉換成JObject,因爲轉換器正在輸出一個字符串,所以這不起作用。 –