2013-01-07 2 views
6

JSON.NET을 사용하여 역 직렬화 할 때 다음 JSON에 문제가 있습니다.JSON을 사용하지 않는 JSON 역 직렬화

{ 
    "?xml": { 
     "@version": "1.0", 
     "@encoding": "utf-8" 
    }, 
    "Persons": { 
     "Person": [{ 
      "@Id": "1", 
      "@Name": "John", 
      "@Surname": "Smith"   
     }, 
     { 
      "@Id": "2", 
      "@Name": "John", 
      "@Surname": "Smith", 
      "Skills": { 
       "Skill": [{ 
        "@Id": "1", 
        "@Name": "Developer"      
       }, 
       { 
        "@Id": "2", 
        "@Name": "Tester" 
       }] 
      } 
     }] 
    } 
} 

나는 다음과 같은 클래스를 사용하고 있습니다 :

public class RootObject 
{ 
    public Xml xml { get; set; } 
    public Persons Persons { get; set; } 
} 

public class Xml 
{ 
    public string version { get; set; } 
    public string encoding { get; set; } 
} 

public class Persons 
{ 
    public List<Person> Person { get; set; } 
} 
public class Skill 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 

public class Skills 
{ 
    public List<Skill> Skill { get; set; } 
} 

public class Person 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public string Surname { get; set; } 
    public Skills Skills { get; set; } 
} 

내가

RootObject persons = JsonConvert.DeserializeObject<RootObject>(json); 

를 역 직렬화 할 나는 다음과 같은 오류 있어요 : 나는를 가정

Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[Project.Models.Persons.Skill]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly. To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.

을 문제는 표기법에 있습니다 :

무엇이 누락 되었습니까?이 문제는 쉽게 해결할 수 있습니까?

는 UPDATE :

그래서 결국 문제는 때때로 JSON 배열

"Skills": { 
       "Skill": [{ 

때로는 JSON 객체

"Skills": { 
       "Skill": { 

했다 그러나 붙여 넣을 때/내 코드를 확인하는 것을 유효성 검사기에 JSON 배열로 형식이 지정되므로 원시 json 문자열을보기 위해 조사 창을 사용하여 검사했습니다.

public class MyConverter : JsonConverter 
    { 
     public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
     { 
      if (reader.TokenType == JsonToken.StartArray) 
      { 
       return serializer.Deserialize<List<Skill>>(reader); 
      } 
      else 
      { 
       Skill skill = serializer.Deserialize<Skill>(reader); 
       return new List<Skill>(new[] { skill}); 
      } 
     }  

     public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
     { 
      writer.WriteValue(value); 
     } 
    } 

가 누군가를 도움이되기를 바랍니다 :

는 거기에서 그것을

public class Skills 
    { 
     [JsonConverter(typeof(MyConverter))] 
     public List<Skill> Skill { get; set; } 
    } 

속성 JsonConverter와 속성을 표시하고 컨버터를 쉽게 작성할 수 있었다.

+0

이 파일에 JSON을 읽고, 귀하의 코드를 역 직렬화, 모든 것이 나를 위해 잘 작동합니다. – Pondidum

+3

답변으로 내 질문을 업데이트했습니다. –

+0

환상적인 답변. 수락 된 답변으로 표시해야합니다. 나를 위해 완벽하게 일했습니다. 내가 만든 변경 사항은 모든 유형 중 하나에 대해 하드 코딩 대신 일반 변환기를 사용하는 것입니다 (예를 들어 스킬) –

답변

4

현재 JSON에서는 이 아니라 Skill에 콜렉션이 포함되어 있다고 설명합니다. 대신 JSON을 시도해보십시오

 "Skills": [ 
      { 
       "@Id": "1", 
       "@Name": "Developer" 
      }, 
      { 
       "@Id": "2", 
       "@Name": "Tester" 
      } 
     ] 

같은 일이 당신이 Persons 수집을 정의하는 방법에 적용됩니다.

편집 :

이 테스트는 나를 위해 전달합니다

[TestFixture] 
    public class JSONTester 
    { 
     [Test] 
     public void Json_deserialize() 
     { 
      var json = @"{ 
    ""?xml"": { 
     ""@version"": ""1.0"", 
     ""@encoding"": ""utf-8"" 
    }, 
    ""Persons"": { 
     ""Person"": [{ 
      ""@Id"": ""1"", 
      ""@Name"": ""John"", 
      ""@Surname"": ""Smith""   
     }, 
     { 
      ""@Id"": ""2"", 
      ""@Name"": ""John"", 
      ""@Surname"": ""Smith"", 
      ""Skills"": { 
       ""Skill"": [{ 
        ""@Id"": ""1"", 
        ""@Name"": ""Developer""      
       }, 
       { 
        ""@Id"": ""2"", 
        ""@Name"": ""Tester"" 
       }] 
      } 
     }] 
    } 
}"; 

      var persons = JsonConvert.DeserializeObject<RootObject>(json); 

      Assert.AreEqual(persons.Persons.Person[1].Skills.Skill.Count, 2); 

     } 

     public class RootObject 
     { 
      public Xml xml { get; set; } 
      public Persons Persons { get; set; } 
     } 

     public class Xml 
     { 
      public string version { get; set; } 
      public string encoding { get; set; } 
     } 

     public class Persons 
     { 
      public List<Person> Person { get; set; } 
     } 
     public class Skill 
     { 
      public int Id { get; set; } 
      public string Name { get; set; } 
     } 

     public class Skills 
     { 
      public List<Skill> Skill { get; set; } 
     } 

     public class Person 
     { 
      public int Id { get; set; } 
      public string Name { get; set; } 
      public string Surname { get; set; } 
      public Skills Skills { get; set; } 
     } 
    } 
+0

JSON을 변경할 수 없습니다. 내가 제안한 것처럼 할 수 있다면 가능합니다. 그러나 이것은 여전히 ​​유효한 JSON입니다. –

+0

나는 그것이 올바른 방향으로 나를 밀어 붙였을 때 당신의 대답에 투표했습니다. 전체 답변은 내 업데이트에 있습니다. –