2017-10-31 13 views
0

일부 Json을 가져 와서 키/값 쌍의 컬렉션으로 파싱하려고하지만 일부 값은 사전 자체가됩니다. 나는 평소 Newtonsoft 비 직렬화를 시도했다. 그것은 가깝지만 옳지 않습니다. 최종 결과는 강력한 형식의 클래스가 아닌 사전이어야합니다. "C# Json 개체 사전에

 var json = File.ReadAllText(@"c:\temp\job.json"); 
     var result = JsonConvert.DeserializeObject<Dictionary<string, object>>(json); 

결과는 거의 정확하지만의 키를 사용하여 항목의 값 :

{ 
    "JobNumber": 1010, 
    "Asset": null, 
    "JobNotes": [ 
    { 
     "NoteText": "It's not working.", 
     "NoteType": "Complaint" 
    }, 
    { 
     "NoteText": "Needs to be fixed", 
     "NoteType": "Job" 
    } 
    ] 
} 

이 내가 역 직렬화하는 데 사용되는 코드는 다음과 같습니다

몇 가지 예를 JSON이다 JobNotes "는 json 문자열입니다. 나는 해석기가 문자열과 객체의 추가 사전에 내부 Json을 재귀 적으로 표현하고 소멸 시키길 원합니다. Newtonsoft 라이브러리에서이 작업을 수행 할 수있는 방법이 있습니까? 또는 트릭을 수행 할 다른 라이브러리가 있습니까? 해당 시점의 기능을 재정의하기 위해 파싱 메서드에 연결할 수 있습니까?

+0

당신이 * 필요 *은'사전 <문자열, 개체> '또는 괜찮을 것 마십시오 역 직렬화 할 수 있습니다 강하게 입력 된 결과가 있습니까? – vzwick

+0

'JobNotes'의 배열을 가지는 클래스를 강하게 입력하면 (자), 자동적으로 그 클래스를 해석해 콜렉션을 생성합니다. – TheVillageIdiot

+0

JSON 문자열을 역 직렬화로 간주 했습니까? 이 질문을보십시오 : [JSON을 C# 동적 객체로 비순 서로 변환 하시겠습니까?] (https://stackoverflow.com/questions/3142495/deserialize-json-into-c-sharp-dynamic-object) – Ellesedil

답변

0

이것은 @ DanielKeogh의 코드의 수정 된 버전입니다. 잘 작동한다. 내가 키에 의해 "뭔가"값을 얻을 수 있도록

{ 
    "JobNumber": 1010, 
    "Asset": null, 
    "JobNotes": [ 
    { 
     "NoteText": "It's not working.", 
     "NoteType": "Complaint" 
    }, 
    { 
     "NoteText": "Needs to be fixed", 
     "NoteType": "Job", 
     "JobNoteNotes": [ 
     { 
      "Something": 1, 
      "Something2": "Test" 
     } 
     ] 
    } 
    ] 
} 

결과는 깊은 세 가지 사전을 종료 :

class Program 
{ 
    static void Main(string[] args) 
    { 
     var json = File.ReadAllText(@"c:\temp\job3.json"); 
     var result = JsonConvert.DeserializeObject<Dictionary<string, object>>(json); 
     RecurseDeserialize(result); 
    } 

    private static void RecurseDeserialize(Dictionary<string, object> result) 
    { 
     //Iterate throgh key/value pairs 
     foreach (var keyValuePair in result.ToArray()) 
     { 
      //Check to see if Newtonsoft thinks this is a JArray 
      var jarray = keyValuePair.Value as JArray; 

      if (jarray != null) 
      { 
       //We have a JArray 

       //Convert JArray back to json and deserialize to a list of dictionaries 
       var dictionaries = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(jarray.ToString()); 

       //Set the result as the dictionary 
       result[keyValuePair.Key] = dictionaries; 

       //Iterate throught the dictionaries 
       foreach (var dictionary in dictionaries) 
       { 
        //Recurse 
        RecurseDeserialize(dictionary); 
       } 
      } 
     } 
    } 
} 

은 JSON이 어떻게되는지 깊은 보여줍니다 수정했습니다. JSON 문자열이 객체를 사용

+0

Json 문서를 무한히 재귀 적으로 찾을 수는 없을 것입니다. > 또한 RecursiveDeserialize를 호출하지 못했습니다. –

+0

이 작업이 진행 중입니다. 언급했듯이, 그것은 아직 그 자체로 재귀하지 않습니다. –

+0

@DanielKeogh 이것은 완전한 대답입니다.그것은 전혀 그렇게 쉽지 않습니다. 내가 Json에서 보여 줬던 것처럼 물체는 3 단계이거나 깊은 곳까지있을 수 있습니다. –

1

이 작업은 약간의 재귀를 통해 수행 할 수 있습니다. 나는 학문적 인 운동으로 너에게까지 IsJson 정의를 떠날 것이다. :)

Dictionary<string, object> RecursiveDeserialize(string json) 
{ 
    var result = JsonConvert.DeserializeObject<Dictionary<string, object>>(json); 
    foreach (var pair in result.ToArray()) 
    { 
     if(IsJson(pair.Value)) 
     { 
      result[pair.Key] = RecursiveDeserialize(pair.Value); 
     } 
    } 
    return result; 
} 
+0

이것은 꽤 가깝습니다. 별로는 아니지만. Newtonsoft가 JobNotes 값에 도달하면 실제로는 문자열이 아니라 JArray입니다. –

+0

그래, 도서관 통화를 모른다. 이것은 아마도 여전히 최선의 접근 방법입니다. –

-1

public class JobNote 
 
{ 
 
    public string NoteText { get; set; } 
 
    public string NoteType { get; set; } 
 
} 
 

 
public class ListJob 
 
{ 
 
    public int JobNumber { get; set; } 
 
    public object Asset { get; set; } 
 
    public List<JobNote> JobNotes { get; set; } 
 
}
다음

당신은