2014-01-10 25 views
7

Json.NETを使用してNoda Timeの値をシリアル化して問題が発生しています。シリアライズは十分単純です。JSON.NETでNoda Timeの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オブジェクトに変換します。これは私が望んでいないものです。 timeStrは米国形式の日付と時刻として出てくる、私はtime.Value<string>() がちょうどJson.NETが既に解析されたいくつかの内部DateTimeオブジェクトにToStringを呼び出すことを推測することから

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>()); 
     } 
} 

。 私は

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

同様に、どのようにシリアル化しますか?あなたの例から、次のように思えますが、 "Test method LiveSerialTests.LinkTests.SerialSnapshotToJSONTest例外がスローされました:System.ArgumentException:オブジェクトがStringにシリアライズされました。 ( "time"、JObject.FromObject(time、serializer)); ' –

+1

' JObject.FromObject(time、serializer) 'ではなく' JToken.FromObject(time、serializer) 'を使います。前者は任意の種類のJToken(この場合は文字列を含むJValue)に変換します。後者は、コンバータが文字列を出力しているので動作しないJObjectに変換することを想定しています。 –

関連する問題