简体   繁体   中英

Deserializing JSON with dynamic keys

I'm quite new to JSON, and am currently learning about (de)serialization. I'm retrieving a JSON string from a webpage and trying to deserialize it into an object. Problem is, the root json key is static, but the underlying keys are dynamic and I cannot anticipate them to deserialize. Here is a mini example of the string :

{
    "daily": {
        "1337990400000": 443447,
        "1338076800000": 444693,
        "1338163200000": 452282,
        "1338249600000": 462189,
        "1338336000000": 466626
    }
}

For another JSON string in my application, I was using a JavascriptSerializer and anticipating the keys using class structure. What's the best way to go about deserializing this string into an object?

Seriously, no need to go down the dynamic route; use

var deser = new JavaScriptSerializer()
    .Deserialize<Dictionary<string, Dictionary<string, int>>>(val);
var justDaily = deser["daily"];

to get a dictionary, and then you can eg

foreach (string key in justDaily.Keys)
    Console.WriteLine(key + ": " + justDaily[key]);

to get the keys present and the corresponding values.

You can use dynamic in .NET 4 or later. For example with JSON.NET I can do:

dynamic obj = JsonConvert.Deserialize<dynamic>("{x: 'hello'}");

You can then do:

var str = obj.x;

However, unsure how it will handle numeric keys. You can of course just use JObject directly itself, for example:

var obj = JObject.Parse("{'123456': 'help'}");
var str = obj["123456"];

Whenever you have JSON with dynamic keys it can usually be deserialized into a Dictionary<string, SomeObject> . Since the inner JSON keys are dynamic (in this question) the JSON can be modelled as:

Dictionary<string, Dictionary<string, int>>

I would recommend using NewtonSoft.Json (JSON.Net) or System.Text.Json (if you're working in .NET-Core 3.0 and up).

Newtonsoft.Json

Use DeserializeObject<T> from JsonConvert :

var response = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, int>>>(json);

System.Text.Json

Use Deserialize<T> from JsonSerializer :

var response = JsonSerializer.Deserialize<Dictionary<string, Dictionary<string, int>>>(json);

This is not convenient to use, because in с# can not be defined a variable starts with a number. Add prefix to keys.

Or try this:

string json = "
{ daily:[
  { key: '1337990400000', val:443447 },
  { key: '1338076800000', val:444693 },
  { key: '1338163200000', val:452282 },
  { key: '1338249600000', val:462189 },
  { key: '1338336000000', val:466626 }]
}";

public class itemClass
{
  public string key; // or int
  public int val;
}

public class items
{
  public itemClass[] daily;
}

items daily = (new JavascriptSerializer()).Deserialize<items>(json);

Then you can:

var itemValue = items.Where(x=>x.key=='1338163200000').Select(x=>x.val).FirstOrDefault();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM