【问题标题】:Deserialize JSON to list with unknown object name in C#在 C# 中反序列化 JSON 以列出具有未知对象名称的列表
【发布时间】:2018-09-15 19:50:28
【问题描述】:

我想反序列化以下 JSON。
问题是对象“ANDE”和“DAR”可以改变。
意味着对象是未知的,并且会根据我想要反序列化的 JSON 而发生变化。
大约 8000 个不同的对象(ANDE、DAR、...)需要反序列化。

{"ANDE":
     {"chart":[
     {"date":"20180914","minute":"09:30"},{"date":"20180914","minute":"13:30"}]},
"DAR":
     {"chart":[
     {"date":"20180914","minute":"09:30"},{"date":"20180914","minute":"13:30"}]}}

我通过 HTTP 响应获取数据并想放入 List:

HttpResponseMessage response = client.GetAsync(API_PATH).GetAwaiter().GetResult();
List historicalDataList = response.Content.ReadAsAsync<List<HistoricalDataResponse>>().GetAwaiter().GetResult();

HistoricalDataResponse 类如下所示:

public class HistoricalDataResponse
{
   public string date { get; set; }
   public string minute { get; set; }
}

如何在 C# 中使用未知对象反序列化这种 JSON? 非常感谢任何帮助。

【问题讨论】:

标签: c# json serialization json-deserialization


【解决方案1】:

那么你应该使用动态变量:

dynamic ReturnValue = JsonConvert.DeserializeObject(jsonstring);

请注意,与动态对象一样,属性是在运行时分配后确定的,因此您不会在设计时获得下拉菜单,而且它的属性在设计时是未知的,而您在设计时测试的属性即使它不正确,您也不会收到错误,并且在分配时会在运行时收到错误。

    dynamic ReturnValue = JsonConvert.DeserializeObject(jsonstring);

try
{
      var a = ReturnValue.ANDE; // will work if it has ANDE property.
      // do what you would do with ANDE
}
catch{}
try
{
      var a = ReturnValue.DAR; // will work if it has DAR property.
      // do what you would do with DAR
}
catch{}

【讨论】:

  • 我无法将 ANDE 放入我的运行代码中,因为我不知道“ANDE”是否在 JSON 中。也许不是“ANDE”,而是“DCUD”或其他东西
  • 可能有大约 8000 种不同的类型。因此不可能将其放入代码中。它需要反序列化 JSON 中的任何对象。
【解决方案2】:

使用字符串作为键类型的字典:

void Main()
{
    var client = new HttpClient();
    HttpResponseMessage response = client.GetAsync("url").GetAwaiter().GetResult();
    var json = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();

    var result = JsonConvert.DeserializeObject<Dictionary<string, DateResponse>>(json);     
    foreach (var element in result)
    {
        var key = element.Key; // ANDE
        foreach (var item in element.Value.Chart)
        {
            var date = item.date;
            var minute = item.minute;
        }
    }
}


public class DateResponse{
    public List<HistoricalDataResponse> Chart { get; set; }
}

public class HistoricalDataResponse
{
    public string date { get; set; }
    public string minute { get; set; }
}

【讨论】:

  • 谢谢,但我还需要结果中的代码“ANDE”和“DAR”。否则我不知道哪个 DataResponse 链接到哪个股票。以及如何使用 API 中的 response.Content 提供 DeserializeObject? HttpResponseMessage response = client.GetAsync(IEXTrading_API_PATH).GetAwaiter().GetResult();
  • DeserializeObject 就像你的ReadAsAsync。为了简单起见,我在复制中使用了它。如果您需要所有数据,只需删除 Select 和 SelectMany 行。代码将成为字典中的键
  • 带有 DeserializeObject 的行有效,但代码行 var result = response.Content.ReadAsAsync&lt;Dictionary&lt;string, DateResponse&gt;&gt;().GetAwaiter().GetResult(); 没有提供我的结果。
  • 你可以试试 ReadAsStringAsync 然后 DeserializeObject 吗?
猜你喜欢
  • 1970-01-01
  • 2021-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多