Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deserialise JSON containing numeric key with Json.NET

Tags:

json

c#

json.net

I would like to deserialize the following JSON (using Json.NET) to an object, but cannot, as the class name would need to begin with a number.

An example of this is the Wikipedia article API. Using the API to provide a JSON response returns something like this. Note the "16689396" inside the "pages" key.

{
   "batchcomplete":"",
   "continue":{
      "grncontinue":"0.893378504602|0.893378998188|35714269|0",
      "continue":"grncontinue||"
   },
   "query":{
      "pages":{
         "16689396":{
            "pageid":16689396,
            "ns":0,
            "title":"Jalan Juru",
            "extract":"<p><b>Jalan Juru</b> (Penang state road <i>P176</i>) is a major road in Penang, Malaysia.</p>\n\n<h2><span id=\"List_of_junctions\">List of junctions</span></h2>\n<p></p>\n<p><br></p>"
         }
      }
   }
}

How could I deserialize this JSON containing a number which changes based on the article?

like image 792
Betato Avatar asked Nov 16 '25 12:11

Betato


2 Answers

It sounds like the Pages property in your Query class would just need to be a Dictionary<int, Page> or Dictionary<string, Page>.

Complete example with the JSON you've provided - I've had to guess at some of the name meanings:

using System;
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;

public class Root
{
    [JsonProperty("batchcomplete")]
    public string BatchComplete { get; set; }
    [JsonProperty("continue")]
    public Continuation Continuation { get; set; }
    [JsonProperty("query")]
    public Query Query { get; set; }
}

public class Continuation
{
    [JsonProperty("grncontinue")]
    public string GrnContinue { get; set; }
    [JsonProperty("continue")]
    public string Continue { get; set; }
}

public class Query
{
    [JsonProperty("pages")]
    public Dictionary<int, Page> Pages { get; set; }
}

public class Page
{
    [JsonProperty("pageid")]
    public int Id { get; set; }
    [JsonProperty("ns")]
    public int Ns { get; set; }
    [JsonProperty("title")]
    public string Title { get; set; }
    [JsonProperty("extract")]
    public string Extract { get; set; }
}

class Test
{
    static void Main()
    {
        string text = File.ReadAllText("test.json");
        var root = JsonConvert.DeserializeObject<Root>(text);
        Console.WriteLine(root.Query.Pages[16689396].Title);
    }    
}
like image 91
Jon Skeet Avatar answered Nov 19 '25 03:11

Jon Skeet


Related question: Json deserialize from wikipedia api with c#

Essentially you need to changes from using a class for the pages to a dictionary, which allows for the dynamic nature of the naming convention.

Class definitions :

public class pageval
{
    public int pageid { get; set; }
    public int ns { get; set; }
    public string title { get; set; }
    public string extract { get; set; }
}

public class Query
{
    public Dictionary<string, pageval>  pages { get; set; }
}

public class Limits
{
    public int extracts { get; set; }
}

public class RootObject
{
    public string batchcomplete { get; set; }
    public Query query { get; set; }
    public Limits limits { get; set; }
}

Deserialization :

var root = JsonConvert.DeserializeObject<RootObject>(__YOUR_JSON_HERE__);
var page = responseJson.query.pages["16689396"];
like image 25
Ben J. Boyle Avatar answered Nov 19 '25 03:11

Ben J. Boyle



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!