0

I have problem when trying to deserialize a json from internet. But I don't know how to deserialize difference types in one array correctly. How to do it correctly? Sorry for my poor english.

Here is json:

{
    "timestamp":"2012-06-19T08:00:49Z",
    "items":[
        {
            "type":"text",
            "content":"etc"
        },
        {
            "type":"video",
            "url":"etc"
        }
        ...
    ]
}

My code:

public interface IPost
{
    string PostType { get; set; }
}    
public class TextPost : IPost
{
    [JsonProperty("type")]
    public string PostType { get; set; }

    [JsonProperty("content")]
    public string Content { get; set; }
}

public class VideoPost : IPost
{
    [JsonProperty("type")]
    public string PostType { get; set; }

    [JsonProperty("url")]
    public string Url { get; set; }
}

public class ResponseData
{
    [JsonProperty("timestamp")]
    public string Timestamp { get; set; }

    [JsonProperty("items")]
    public List<IPost> Items { get; set; }
}
Nguyen Kien
  • 1,897
  • 2
  • 16
  • 22

1 Answers1

1

I figured out a way to parse it. By using JsonConverter. Here is my Converter class:

public class PostsConverter : JsonConverter
{

    // Create an instance
    protected IPost Create(JObject jObject)
    {
        if (PostType("Text", jObject))  return new Text();
        if (PostType("Video", jObject))  return new Video();
        throw new Exception("Error");
    }

    public override bool CanConvert(Type objectType)
    {
        throw new NotImplementedException();
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var list = new List<IPost>();

        var arr = JArray.Load(reader);

        foreach (var item in arr)
        {
            var obj = JObject.Load(item.CreateReader());

            // Create target object based on JObject
            var post = Create(obj);

            // Populate the object properties
            serializer.Populate(obj.CreateReader(), post);

            list.Add(post);
        }
        return list;
    }

    private bool PostType(string type, JObject jObject)
    {
        return jObject["PostType"] != null && jObject["PostType"].Value<string>() == type;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        // I don't need serialize object
        throw new NotImplementedException();
    }
}

Response class:

public class ResponseData
{
    [JsonProperty("timestamp")]
    public string Timestamp { get; set; }

    [JsonConverter(typeof(PostsConverter))]
    [JsonProperty("items")]
    public List<IPost> Items { get; set; }
}

Now I can parse it:

var myData = JsonConvert.DeserializeObject<ResponseData>(json);
Nguyen Kien
  • 1,897
  • 2
  • 16
  • 22