使用动态密钥反序列化JSON

时间:2012-11-22 17:44:41

标签: c# json dynamic deserialization

我对JSON很新,目前正在学习(de)序列化。 我正在从网页中检索JSON字符串并尝试将其反序列化为对象。问题是,根json密钥是静态的,但底层密钥是动态的,我无法预期它们反序列化。以下是字符串的一个小例子:

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

对于我的应用程序中的另一个JSON字符串,我使用的是JavascriptSerializer并使用类结构预测密钥。将此字符串反序列化为对象的最佳方法是什么?

4 个答案:

答案 0 :(得分:20)

说真的,没必要走下动态路线;使用

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

获取字典,然后就可以了。

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

获取密钥和相应的值。

答案 1 :(得分:4)

您可以在.NET 4或更高版本中使用dynamic。例如,使用JSON.NET,我可以这样做:

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

然后你可以这样做:

var str = obj.x;

但是,不确定它将如何处理数字键。您当然可以直接使用JObject,例如:

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

答案 2 :(得分:0)

只要您具有带有动态键的JSON,通常都可以将其反序列化为Dictionary<string, SomeObject>。由于内部JSON键是动态的(在此问题中),因此JSON可以建模为:

Dictionary<string, Dictionary<string, int>>

我建议使用NewtonSoft.Json(JSON.Net)或System.Text.Json(如果您使用的是.NET-Core 3.0及更高版本)。

Newtonsoft.Json

使用DeserializeObject<T>中的JsonConvert

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

System.Text.Json

使用Deserialize<T>中的JsonSerializer

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

答案 3 :(得分:-1)

这不方便使用,因为无法定义с#,变量以数字开头。为密钥添加前缀。

或试试这个:

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);

然后你可以:

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