Reputation: 1468
I want to convert HackerNews API Items with Newtonsoft.
I would like to look only at the type field and then convert to the right item of the type, so I don't have all fields in all items.
I want to be able to determine the class by type and then deserialize.
Upvotes: 0
Views: 255
Reputation: 1468
I don't know if this is the best solution.
Code for deserialize
var item = JsonConvert.DeserializeObject<ItemType>(responseString);
switch (item.Type)
{
case Type.Job:
return JsonConvert.DeserializeObject<Job>(responseString);
case Type.Story:
return JsonConvert.DeserializeObject<Story>(responseString);
case Type.Comment:
return JsonConvert.DeserializeObject<Comment>(responseString);
case Type.Poll:
return JsonConvert.DeserializeObject<Poll>(responseString);
case Type.PollOpt:
return JsonConvert.DeserializeObject<PollOpt>(responseString);
default:
throw new ArgumentOutOfRangeException();
}
All items classes
public class ItemType
{
public Type Type { get; set; }
}
public enum Type
{
None,
Job,
Story,
Comment,
Poll,
PollOpt,
}
public interface IItem
{
}
public class Story : IItem
{
public string By { get; set; }
public long Descendants { get; set; }
public long Id { get; set; }
public List<long> Kids { get; set; }
public long Score { get; set; }
public long Time { get; set; }
public string Title { get; set; }
public string Type { get; set; }
public Uri Url { get; set; }
}
public class Comment : IItem
{
public string By { get; set; }
public long Id { get; set; }
public List<long> Kids { get; set; }
public long Parent { get; set; }
public string Text { get; set; }
public long Time { get; set; }
public string Type { get; set; }
}
public class Job : IItem
{
public string By { get; set; }
public long Id { get; set; }
public long Score { get; set; }
public string Text { get; set; }
public long Time { get; set; }
public string Title { get; set; }
public string Type { get; set; }
public string Url { get; set; }
}
public class Poll : IItem
{
public string By { get; set; }
public long Descendants { get; set; }
public long Id { get; set; }
public List<long> Kids { get; set; }
public List<long> Parts { get; set; }
public long Score { get; set; }
public string Text { get; set; }
public long Time { get; set; }
public string Title { get; set; }
public string Type { get; set; }
}
public class PollOpt : IItem
{
public string By { get; set; }
public long Id { get; set; }
public long Poll { get; set; }
public long Score { get; set; }
public string Text { get; set; }
public long Time { get; set; }
public string Type { get; set; }
}
Upvotes: 0
Reputation: 1499
Have a Crude POCO called TypeIdentifier, which has only Type to identify the Type alone and then use the original POCO.
Use Quicktype to convert any JSON to C# Classes(POCO) and use the JsonConvert.Deserialize to deserialize the same.
public class HakernewsTypeIdentifier
{
[JsonProperty("type")]
public string Type { get; set; }
}
public class HakerNewsStory
{
[JsonProperty("by")]
public string By { get; set; }
[JsonProperty("descendants")]
public long Descendants { get; set; }
[JsonProperty("id")]
public long Id { get; set; }
[JsonProperty("kids")]
public long[] Kids { get; set; }
[JsonProperty("score")]
public long Score { get; set; }
[JsonProperty("time")]
public long Time { get; set; }
[JsonProperty("title")]
public string Title { get; set; }
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("url")]
public Uri Url { get; set; }
}
// Use Libraries like RestSharp to fetch the Data
// Find the Type
var typeID = JsonConvert.DeserializeObject<HakernewsTypeIdentifier>(json);
// Deserialize once again based on the Type
if(typeID.type == "story")
var story = JsonConvert.DeserializeObject<HakerNewsStory>(json);
Hope this helps.
Upvotes: 2