2013-01-07 54 views
6

當使用JSON.NET反序列化時,我遇到下面的JSON問題。反序列化JSON不與JSON.NET一起工作

{ 
    "?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.

我猜想問題在於:

"Skills": { 
      "Skill": [{ 

我錯過了什麼,有沒有一個簡單的解決這個問題?

UPDATE:

所以最後的問題是,它有時JSON陣列

"Skills": { 
       "Skill": [{ 

,有時一個JSON對象

"Skills": { 
       "Skill": { 

但粘貼時/檢查我的代碼進入驗證器,它將始終格式化爲JSON數組,因此我使用觀察窗口檢查了它,以查看原始JSON字符串。

從那裏很容易,以紀念與JsonConverter財產屬性

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

和寫入轉換器:

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

希望它可以幫助別人。

+0

讀你的JSON從文件,並與您的代碼反序列化,這一切工作正常,我。 – Pondidum

+3

我已經用一個答案更新了我的問題。 –

+0

夢幻般的答案。您應該將其標記爲已接受的答案。爲我完美工作。只有改變我是讓轉換器通用而不是硬編碼的任何一種類型(技能在你的例子) –

回答

4

我認爲,使用您當前的JSON,您描述的是Skill包含一個集合,而不是Skills。試試這個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

我已經投了你的答案,因爲它把我推向了正確的方向。整個答案在我的更新中。 –