2012-03-05 12 views
11

"type"という名前のフィールドを含むjsonデータのストリームが与えられました。このタイプフィールドは、実行時に作成する必要のあるオブジェクトのタイプを記述します。 JsonTextReaderを2回使用することができないようで、テキストリーダーを最初にリセットすることはできません。JsonTextReaderを2回使用する方法

using (var streamReader = new StreamReader(stream, Encoding)) 
using (var jsonTextReader = new JsonTextReader(streamReader)) 
{ 
    JToken token = JObject.Load(jsonTextReader); 
    var type = (string) token.SelectToken("type"); 
    var modelType = Type.GetType("Project." + type + ", Project"); 

    // Fails here 
    var obj = serializer.Deserialize(jsonTextReader, modelType); 
} 

このエラーメッセージが表示されます。 オブジェクトを逆シリアル化する際に予期しないトークン:EndObject。

答えて

10

JTokenからJsonReaderを作成することができます。

JsonReader reader = token.CreateReader(); 
+0

それはトリックでした!ありがとう。 – Phil

0

もう少しテストを行い、以下のことが分かった。

  1. 設定JsonTextReader.CloseInput = false
  2. using文を閉じることで)JsonTextReaderを破壊
  3. 設定StreamReader.BaseStream.Position = 0
  4. それはこのようになります新しいJsonTextReader

を作成します。

using (var streamReader = new StreamReader(stream, encoding)) 
{ 
    Type modelType = null; 

    using (var jsonTextReader = new JsonTextReader(streamReader)) 
    { 
     jsonTextReader.CloseInput = false; 

     JToken token = JObject.Load(jsonTextReader); 
     string type = (string)token.SelectToken("type"); 
     modelType = Type.GetType("Project." + type + ", Project"); 
    } 

    streamReader.BaseStream.Position = 0; 

    using (var jsonTextReader = new JsonTextReader(streamReader)) 
    { 
     var obj = serializer.Deserialize(jsonTextReader, modelType); 
    } 

} 
+0

これは機能しません。 'StreamReader'のコンストラクタに' leaveOpen'パラメータを指定しない限り、それは基礎となるストリームを閉じます。これを修正した場合、問題のコードが機能していても機能しますが、そうではありません。 – svick

+0

オリジナルの投稿がテストされましたが、間違っています。私はそれを更新しました。 – tstuts

1

は、begginningにあなたの読者をリセット0

streamReader.BaseStream.Position = 0; 

編集に基本となるストリームのPositionプロパティを設定するには:これはあなたの基になるストリームをリセットしますが 、jsonTextReaderは前進のみ定義によってですこれは、行番号と位置が読み取り専用であることを意味します。これを動作させるには、streamReaderの位置をリセットしてからnew JsonTextReaderオブジェクトにフィードする必要があります。

残念なことにPhilは、転送専用なので、JsonTextReaderを2回読み取る方法はありません。

参照: http://james.newtonking.com/projects/json/help/html/T_Newtonsoft_Json_JsonTextReader.htm "シリアライズされたJsonデータへの高速で非キャッシュの転送専用アクセスを提供するリーダーを表します。"

+0

これが正しく動作することは確かですか? 'StreamReader'と' JsonTextReader'はおそらくこれを行うことでリセットされない内部状態を保持しています。 – svick

0

私はジェームズ・ニュートン王の勧告に従って、など、ラージオブジェクトヒープを避け、メモリ効率的なフォーマットでin my blogJsonTextReaderを使用してカバーしています。 JsonTextReaderの実装について心配することなく、これと提供されたコードを活用してJSONを何度も読むことができます。

コメントとフィードバックはいつでも歓迎します。

関連する問題