反序列化动态 JSON C#



我需要反序列化以下json:

    {
      "1": {
        "oid": "46",
        "order": "SD9999999999999",
        "date": "2015-08-18 14:17:05",
        "item": {
          "0": {
            "guid": "DEF456"
            "price": "100.00"
          },
          "1": {
            "guid": "ABC123",
            "price": "99.99"
          }
        }
      },
      "2": {
        "oid": "765",
        "order": "SD0000000000000",
        "date": "2015-08-18 14:17:05",
        "item": {
          "0": {
            "guid": "GHI789"
            "price": "10.00"
          },
          "1": {
            "guid": "XYZ123",
            "price": "9.99"
          }
       }
    },
    "store": 111,
    "time": "2015-09-01 17:51:22"
  }
订单

数量以及每个订单中的项目数量未知。

我尝试制作一个订单列表并动态循环,然后将每个订单添加到列表中,但这并不能解释项目是动态的,项目最终等于 null。有什么想法吗?

可以使用JObject/JToken(在修复了json中缺少的,之后)。

var json = System.IO.File.ReadAllText("test.json");
var jobj = Newtonsoft.Json.Linq.JObject.Parse(json);
//exclude "store" and "time"
var orders = jobj.Children().Where(x => x.Path != "store" && x.Path != "time").ToList();
//iterate over orders
foreach (var order in orders)
{
    //"name" of order
    var orderName = order.Path;
    //and contents
    var orderItems = order.First()["item"].ToList();
    foreach (var item in orderItems)
    {
        var itemName = item.Path;
        var itemContents = item.First();
        var guid = (String)itemContents["guid"];
        var price = Double.Parse((String)itemContents["price"]);
    }
}

为了完整起见,还将代码反序列化为Dictionary<String, dynamic>

var dynObj = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<String, dynamic>>(json);
var dynOrders = dynObj.Where(x => x.Key != "store" && x.Key != "time").ToList();
foreach (dynamic order in dynOrders)
{
    var orderName = order.Key;
    var orderItems = order.Value.item;
    foreach (var item in orderItems)
    {
        var itemName = item.Name;
        var guid = (String)item.Value.guid;
        var price = Double.Parse((String)item.Value.price);
    }
}

我会说,对于这两个,我必须设置断点并检查对象,看看我必须使用什么以及什么可以工作才能获得这些数据。与数组相比,"字典"样式的对象在 C# 中更笨拙。我确实通过这个答案找到了另一种方法来做到这一点。虽然最详细,但跨对象级别也最一致。

//"force" to use IDictionary interface
IDictionary<string, JToken> dict = Newtonsoft.Json.Linq.JObject.Parse(json);
var dictOrders = dict.Where(x => x.Key != "store" && x.Key != "time").ToList();
foreach (var order in dictOrders)
{
    var orderName = order.Key;
    var orderProps = (IDictionary<string, JToken>)order.Value;
    var oid = Int32.Parse((String)orderProps["oid"]);
    var orderX = (String)orderProps["order"];
    var date = DateTime.Parse((String)orderProps["date"]);
    var orderItems = (IDictionary<string, JToken>)orderProps["item"];
    foreach (var item in orderItems)
    {
        var itemName = item.Key;
        var itemContents = (IDictionary<string, JToken>)item.Value;
        var guid = (String)itemContents["guid"];
        var price = Double.Parse((String)itemContents["price"]);
    }
}

通过使用这种模式,你应该能够获取任何JToken,将其强制转换为IDictionary<string, JToken>,然后以一致的方式处理其内容,使用属性名称的Key和内容的Value(您还将强制转换为IDictionary以便您可以根据需要下降对象)。

最新更新