14

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

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

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

4

4 回答 4

34

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

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

获取存在的键和相应的值。

于 2012-11-22T18:10:54.203 回答
6

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

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

然后你可以这样做:

var str = obj.x;

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

var obj = JObject.Parse("{'123456': 'help'}");
var str = obj["123456"];
于 2012-11-22T17:49:52.443 回答
2

每当您拥有带有动态键的 JSON 时,通常可以将其反序列化为Dictionary<string, SomeObject>. 由于内部 JSON 键是动态的(在这个问题中),因此 JSON 可以建模为:

Dictionary<string, Dictionary<string, int>>

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

牛顿软件.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);
于 2019-12-16T13:54:14.663 回答
-2

这使用起来不方便,因为在с#中不能定义一个以数字开头的变量。为键添加前缀。

或者试试这个:

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();
于 2012-11-22T17:49:52.260 回答