This Imgur api call returns a list containing both Gallery Image and Gallery Album classes represented in JSON.
I can't see how to deserialize these automatically using Json.NET given that there is no $type property telling the deserializer which class is meant to be represented. There is a property called "IsAlbum" that can be used to differentiate between the two.
This question appears to show one method but it looks like a bit of a hack.
How do I go about deserializing these classes? (using C#, Json.NET).
Sample Data:
Gallery Image
{ "id": "OUHDm", "title": "My most recent drawing. Spent over 100 hours.", ... "is_album": false }
Gallery Album
{ "id": "lDRB2", "title": "Imgur Office", ... "is_album": true, "images_count": 3, "images": [ { "id": "24nLu", ... "link": "http://i.imgur.com/24nLu.jpg" }, { "id": "Ziz25", ... "link": "http://i.imgur.com/Ziz25.jpg" }, { "id": "9tzW6", ... "link": "http://i.imgur.com/9tzW6.jpg" } ] } }
There is no polymorphic deserialization (equivalent to Newtonsoft. Json's TypeNameHandling ) support built-in to System.
You can use this schema when defining XML Type hierarchies by using only the base XML Types. The XML schema defines XML Types that inherit from each other. In the JSON, an object carries no additional information about the type.
JSON is a format that encodes objects in a string. Serialization means to convert an object into that string, and deserialization is its inverse operation (convert string -> object).
The JsonSerializer is a static class in the System. Text. Json namespace. It provides functionality for serializing objects to a JSON string and deserializing from a JSON string to objects.
You can do this fairly easily by creating a custom JsonConverter
to handle the object instantiation. Assuming you have your classes defined something like this:
public abstract class GalleryItem { public string id { get; set; } public string title { get; set; } public string link { get; set; } public bool is_album { get; set; } } public class GalleryImage : GalleryItem { // ... } public class GalleryAlbum : GalleryItem { public int images_count { get; set; } public List<GalleryImage> images { get; set; } }
You would create the converter like this:
public class GalleryItemConverter : JsonConverter { public override bool CanConvert(Type objectType) { return typeof(GalleryItem).IsAssignableFrom(objectType); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { JObject jo = JObject.Load(reader); // Using a nullable bool here in case "is_album" is not present on an item bool? isAlbum = (bool?)jo["is_album"]; GalleryItem item; if (isAlbum.GetValueOrDefault()) { item = new GalleryAlbum(); } else { item = new GalleryImage(); } serializer.Populate(jo.CreateReader(), item); return item; } public override bool CanWrite { get { return false; } } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { throw new NotImplementedException(); } }
Here's an example program showing the converter in action:
class Program { static void Main(string[] args) { string json = @" [ { ""id"": ""OUHDm"", ""title"": ""My most recent drawing. Spent over 100 hours."", ""link"": ""http://i.imgur.com/OUHDm.jpg"", ""is_album"": false }, { ""id"": ""lDRB2"", ""title"": ""Imgur Office"", ""link"": ""http://alanbox.imgur.com/a/lDRB2"", ""is_album"": true, ""images_count"": 3, ""images"": [ { ""id"": ""24nLu"", ""link"": ""http://i.imgur.com/24nLu.jpg"" }, { ""id"": ""Ziz25"", ""link"": ""http://i.imgur.com/Ziz25.jpg"" }, { ""id"": ""9tzW6"", ""link"": ""http://i.imgur.com/9tzW6.jpg"" } ] } ]"; List<GalleryItem> items = JsonConvert.DeserializeObject<List<GalleryItem>>(json, new GalleryItemConverter()); foreach (GalleryItem item in items) { Console.WriteLine("id: " + item.id); Console.WriteLine("title: " + item.title); Console.WriteLine("link: " + item.link); if (item.is_album) { GalleryAlbum album = (GalleryAlbum)item; Console.WriteLine("album images (" + album.images_count + "):"); foreach (GalleryImage image in album.images) { Console.WriteLine(" id: " + image.id); Console.WriteLine(" link: " + image.link); } } Console.WriteLine(); } } }
And here is the output of the above program:
id: OUHDm title: My most recent drawing. Spent over 100 hours. link: http://i.imgur.com/OUHDm.jpg id: lDRB2 title: Imgur Office link: http://alanbox.imgur.com/a/lDRB2 album images (3): id: 24nLu link: http://i.imgur.com/24nLu.jpg id: Ziz25 link: http://i.imgur.com/Ziz25.jpg id: 9tzW6 link: http://i.imgur.com/9tzW6.jpg
Fiddle: https://dotnetfiddle.net/1kplME
Simply with JsonSubTypes attributes that work with Json.NET
[JsonConverter(typeof(JsonSubtypes), "is_album")] [JsonSubtypes.KnownSubType(typeof(GalleryAlbum), true)] [JsonSubtypes.KnownSubType(typeof(GalleryImage), false)] public abstract class GalleryItem { public string id { get; set; } public string title { get; set; } public string link { get; set; } public bool is_album { get; set; } } public class GalleryImage : GalleryItem { // ... } public class GalleryAlbum : GalleryItem { public int images_count { get; set; } public List<GalleryImage> images { get; set; } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With