2017-03-17 183 views
0

我嘗試通過使用一些回答問題的代碼來創建自定義JSON轉換器。如何將JSON數組或JSON對象轉換爲對象列表?

public class SingleValueArrayConverter<T> : JsonConverter 
{ 
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     if (reader.TokenType == JsonToken.StartObject) 
     {     
      T instance = serializer.Deserialize<T>(reader); 
      return new List<T>() { instance }; 
     } 
     else if (reader.TokenType == JsonToken.StartArray) 
     { 
      return serializer.Deserialize<List<T>>(reader); 
     } 

     return null; 
    } 

    public override bool CanConvert(Type objectType) 
    { 
     return true; 
    } 

    public override bool CanWrite 
    { 
     get { return false; } 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 
} 

這是我的示例模型類。

public class Foo 
{ 
    [JsonProperty("type")] 
    public string Type; 
} 

我使用下面的代碼來執行。它會導致堆棧溢出錯誤。

var converter = new SingleValueArrayConverter<Foo>(); 

var test1 = "[{ \"type\": \"test\" }]"; 
var result1 = JsonConvert.DeserializeObject<List<Foo>>(test1, converter); 

var test2 = "{ \"type\": \"test\" }"; 
var result2 = JsonConvert.DeserializeObject<List<Foo>>(test2, converter); 

enter image description here

+1

你在偷看下一個標記,但沒有閱讀(從而將它從流中刪除)。在自定義讀/寫方法中,您應該使用* reader *本身。請參閱[本答案](http://stackoverflow.com/a/8031283/563532)以瞭解您的閱讀方法應該如何表現的示例。 – Rob

回答

0

轉換任何JSON來.NET對象的最簡單的方法是使用「ToObject」 JToken對象的方法。

public class FooConverter : JsonConverter 
{ 
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     var token = JToken.Load(reader); 

     if (token.Type == JTokenType.Array) 
     { 
      return token.ToObject<List<Foo>>(); 
     } 

     var item = token.ToObject<Foo>(); 

     return new List<Foo> { item }; 
    } 

    public override bool CanConvert(Type objectType) 
    { 
     return true; 
    } 

    public override bool CanWrite 
    { 
     get { return false; } 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 
} 

PS。 JToken object是任何JSON數據的基類,因此我們可以將JToken對象轉換爲任何適當的類型。

JToken    - abstract base class  
    JContainer  - abstract base class of JTokens that can contain other JTokens 
     JArray  - represents an JSON array (contains an ordered list of JTokens) 
     JObject  - represents an JSON object (contains a collection of JProperties) 
     JProperty - represents a JSON property (a name/JToken pair inside a JObject) 
    JValue   - represents a primitive JSON value (string, number, boolean, null)