2012-03-05 2 views
11

"type"이라는 필드가 들어있는 json 데이터 스트림이 제공됩니다. 이 유형 필드는 런타임에 작성해야하는 오브젝트 유형을 설명합니다. JsonTextReader를 두 번 사용할 수 없으며 텍스트 판독기를 처음부터 다시 설정할 수 없습니다.JsonTextReader를 두 번 사용하는 방법

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

나는 더 많은 테스트를했고 다음과 같은 결과가 있음을 발견했습니다. 세트 JsonTextReader.CloseInput = false

  • JsonTextReader
  • StreamReader.BaseStream.Position = 0
  • 를 설정합니다 (using 문을 닫아) 파괴

    1. 과 같은 새로운 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; 
    

    편집에 기본이되는 스트림의 위치 속성을 설정하려면이 당신의 기본이되는 스트림을 재설정하는 동안 의 jsonTextReader는 앞으로 만 정의에 의해입니다 이것은 행 번호와 위치가 읽기 전용임을 의미합니다. 이 작업을하려면 streamReader 위치를 재설정 한 다음 JsonTextReader 객체로 피드해야합니다.

    불행히도 Phil은 앞으로 만 진행되므로 JsonTextReader를 두 번 읽는 방법이 없습니다.

    참조 : ". 직렬화 된 JSON 데이터에 빠르고, 캐시되지 않으며 앞으로 전용 액세스를 제공하는 판독기를 나타냅니다"http://james.newtonking.com/projects/json/help/html/T_Newtonsoft_Json_JsonTextReader.htm

    +0

    이것이 올바르게 작동 할 확신합니까? 'StreamReader'와'JsonTextReader'는 아마 이것으로 리셋되지 않는 내부 상태를 유지할 것입니다. – svick

    0

    나는 제임스 뉴턴 왕의 권고에 따라 등 대형 오브젝트 힙, in my blog을 피하고, 메모리 효율적인 형식으로 JsonTextReader를 사용하여 다룹니다. JsonTextReader의 기본 구현에 대해 걱정할 필요없이이 코드와 제공된 코드를 활용하여 JSON을 여러 번 읽을 수 있습니다.

    언제나 환영합니다.