2013-01-07 21 views
6

JSON.NET kullanarak seri hale getirme sırasında aşağıdaki JSON ile ilgili bir sorunum var.JSON.NET ile çalışmayan JSON Deserialize

{ 
    "?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" 
       }] 
      } 
     }] 
    } 
} 

şu dersleri kullanıyorum:

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

i

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

serisini çalıştığınızda i aşağıdaki hata var: herhalde

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.

sorun gösterimde:

"Skills": { 
      "Skill": [{ 

Neyi kaçırıyorum, bu soruna kolay bir çözüm var mı?

GÜNCELLEME:

Sonunda sorun bazen bir JSON dizisi

"Skills": { 
       "Skill": [{ 

ve bazen bir JSON nesnesi

"Skills": { 
       "Skill": { 

oldu Ama yapıştırırken/kodumu kontrol ediyordu Doğrulayıcılar içine her zaman bir JSON dizisi olarak biçimlendirilmiş olurdu, bu yüzden ham json dizesini görmek için izleme penceresini kullanarak inceledim.

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

o birilerine yardımcı olur umarım:

Oradan

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

özniteliği bir JsonConverter ile mülk işaretlemek ve dönüştürücü yazmak kolay oldu.

+0

bir dosyadan da json Okuma ve sizin koduyla deserializing, hepsi benim için çalışıyor. – Pondidum

+3

Sorumu bir yanıtla güncelledim. –

+0

Fantastik cevap. Kabul edilen cevap olarak işaretlemelisiniz. Benim için mükemmel çalıştı. Sadece yaptığım değişiklik, herhangi bir tür için sabit kodlama yerine dönüştürücü jenerik yapmaktı (örneğinizdeki yetenek) –

cevap

4

Geçerli JSON'unuz ile, Skill'un Skills numaralı bir koleksiyonu içerdiğini açıklıyorsunuz. Bunun yerine bu JSON deneyin:

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

aynı şey Persons koleksiyonunu tanımlayan nasıl uygulanır.

DÜZENLEME:

Bu test benim için geçer:

[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'u değiştiremem, eğer teklif ettiğin gibi yapabilirdim. Ama bu hala geçerli bir JSON. –

+0

Beni doğru yöne ittiğinden cevabınızı oylamadım. Bütün cevap güncellememde. –

İlgili konular