In order to give you strong typing, if the schema is always with a:
- Summary
- Varying number of "Relevances"
You can a JsonConverter class to deserialize it into a class named Summary, and a List of "Relevances". Like so:
Execution:
string json = @"{
""searchresult"":{
""summary"":{
""page"":""1 of 451"",
""relevancy"":""100% - 99%"",
""count"":25,
""query"":""some search query""
},
""0"":{
""relevance"":100,
""id"":343,
},
""1"":{
""relevance"":99,
""id"":434,
}
}
}";
var searchResult = JsonConvert.DeserializeObject<SearchResult>(json);
ViewModels
[JsonConverter(typeof(Converter))]
class SearchResult
{
public Summary Summary { get; set; }
public List<RelevanceWrapper> Relevances { get; set; }
}
class Summary
{
public string Page { get; set; }
public string Relevancy { get; set; }
public int Count { get; set; }
public string Query { get; set; }
}
class RelevanceWrapper
{
public int Id { get; set; }
public int Relevance { get; set; }
}
JsonConverter
class Converter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject jObject = JObject.Load(reader);
var searchResultToken = jObject.GetValue("searchresult");
var searchResult = new SearchResult()
{
Relevances = new List<RelevanceWrapper>()
};
foreach (JProperty prop in searchResultToken)
{
if (prop.Name == "summary")
{
searchResult.Summary = prop.Value.ToObject<Summary>();
}
else
{
searchResult.Relevances.Add(prop.Value.ToObject<RelevanceWrapper>());
}
}
return searchResult;
}
public override bool CanConvert(Type objectType)
{
throw new NotImplementedException();
}
}
There are more ways to do this in ReadJson, as well as other ways of deserializing with Json.Net, but I find this way readable enough to understand what's going on.