I have a JSON “multi-level” response that I need to deserialize and from the deserialized classes structure I need to extract all the objects of a certain class.
Below the code I’m using, at the end I find that my result is empty, not populated.
// given these two classes:
[DataContract]
public class ThingsList
{
[DataMember(Name = "status")]
public string Status { get; set; }
[DataMember(Name = "since")]
public double Since { get; set; }
[DataMember(Name = "list")]
public Dictionary<string, ThingsListItem> Items { get; set; }
public DateTime SinceDate { get { return UnixTime.ToDateTime(Since); } }
}
[DataContract]
public class ThingsListItem
{
[DataMember(Name = "url")]
public string Url { get; set; }
[DataMember(Name = "title")]
public string Title { get; set; }
}
// I can deserialize my json to this structure with:
ThingsList results = JsonConvert.DeserializeObject<ThingsList>(e.Result);
// now I need to "extract" only the ThingsListItem objects, and I'm trying this:
var theList = from item in results.Items.OfType<ThingsListItem>()
select new
{
Title = item.Title,
Url = item.Url
};
// but "theList" is not populated.
The points here are (I believe):
– I try to use results.Items.OfType() in order to extract only the ThingsListItem objects, that in the “upper” class are declared in the
public Dictionary Items { get; set; }
row.
Any idea? Tell if it’s not clear…
Thanks
Andrea
EDIT: updated my response for clarity.
Since your Dictionary values are of type
ThingsListItemyou can access them directly by using the Dictionary’sValuesproperty. There is no need to useOfTypeto check their type and extract them. Simply use:The
Valuesproperty would return anICollection<ThingsListItem>. You can then iterate over the results with a foreach. LINQ does not have to be used.While the
Valuesproperty described above should be sufficient, I will point out a few issues with your original LINQ query attempt.1) The following query is probably what you were after. Again, the Dictionary’s
Valuesproperty is key (no pun intended) to accessing the items:2) Why are you using
new? That will return anIEnumerableof anonymous types. You already have a defined class, so why project into a new anonymous type? You should retain the underlyingThingsListItemitems by selecting the item directly to get anIEnumerable<ThingsListItem>:You would usually project into a new anonymous type to define a type with data properties you are interested in. Generally you would use them immediately after the query, whereas a selection into an existing class could be used immediately or passed around to other methods that are expecting that type.
Hopefully this has cleared up some questions for you and you have a better idea of using LINQ and when to use the
newkeyword. To reiterate, for your purposes it seems theValuesproperty should suffice. Using LINQ to select the item is redundant when there are other immediate means to do so.