Reputation: 1526
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?
Upvotes: 17
Views: 30302
Reputation: 37909
Here is a concrete example:
{
"translation": {
"el": {
"name": "Greek",
"nativeName": "Ελληνικά",
"dir": "ltr"
},
"en": {
"name": "English",
"nativeName": "English",
"dir": "ltr"
}
}
}
var dictionary = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, Dictionary<string,string>>>>(json);
//There is only one top level item, so get that here.
var languages = dictionary["translation"];
List<LanguageInfo> languageInfos = new List<LanguageInfo>();
foreach (var language in languages) {
var newLanguageInfo = new LanguageInfo();
newLanguageInfo.LanguageId = language.Key;
newLanguageInfo.EnglishName = language.Value["name"];
newLanguageInfo.NativeName = language.Value["nativeName"];
newLanguageInfo.Direction = language.Value["dir"];
languageInfos.Add(newLanguageInfo);
}
public class LanguageInfo
{
public string LanguageId { get; set; }
public string EnglishName { get; set; }
public string NativeName { get; set; }
public string Direction { get; set; }
}
Upvotes: 0
Reputation: 16701
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);
Upvotes: 6
Reputation: 50114
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 e.g.
foreach (string key in justDaily.Keys)
Console.WriteLine(key + ": " + justDaily[key]);
to get the keys present and the corresponding values.
Upvotes: 37
Reputation: 2493
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();
Upvotes: -2
Reputation: 29668
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"];
Upvotes: 5