此Imgur api调用返回一个列表,其中包含以JSON表示的 Gallery Image 和 Gallery Album 类。
鉴于没有$ type属性告诉反序列化器要表示哪个类,因此我看不到如何使用Json.NET自动反序列化。有一个称为“ IsAlbum”的属性,可用于区分两者。
这个问题似乎显示出一种方法,但看起来有点像个hack。
我该如何反序列化这些类? (使用C#,Json.NET)。
样本数据:
图库图片
{ "id": "OUHDm", "title": "My most recent drawing. Spent over 100 hours.", ... "is_album": false }
画廊专辑
{ "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" } ] } }
通过创建JsonConverter用于处理对象实例化的自定义,您可以相当轻松地做到这一点。假设您的类定义如下:
JsonConverter
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; } }
您将这样创建转换器:
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(); } }
这是一个示例程序,显示了运行中的转换器:
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(); } } }
这是上面程序的输出:
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
小提琴:https : //dotnetfiddle.net/1kplME