【问题标题】:Deserialize odd JSON dictionary反序列化奇数 JSON 字典
【发布时间】:2014-04-06 09:01:11
【问题描述】:

我一生都无法弄清楚如何让这个 JSON 反序列化为我可以在代码中使用和阅读的东西。我创建了一个类并在每个属性上使用 JsonProperty 来处理 json 名称中句点的无效使用。但我不知道如何创建根对象。带有数字的属性是随机的,就像一本字典。但是 recsindb 和 recsonpage 是静态名称。

{
    "1": {
        "orders.orderid":"538",
        "entity.customerid":"109",
        "entity.entityid":"538",
    },
    "2": {
        "orders.orderid":"536",
        "entity.customerid":"108",
        "entity.entityid":"536",
    },
    "recsindb":"2",
    "recsonpage":"2"
}

【问题讨论】:

  • 我已将几天前刚刚回答的问答标记为可能重复。标题不同,但对您来说也是一个可能的解决方案!
  • @MatíasFidemraizer 这根本不像另一个问题,没有什么像另一个问题那样具有高度动态性。这是与属性混合的字典之间的问题。布赖恩的回答实际上一针见血。
  • 你可以用 ExpandoObject 解决这个问题。
  • 可能是这样,但这不是我想要的。从我读到的关于 ExpandoObject 的内容来看,不,那仍然行不通。这个问题已经回答了。您能否删除链接的答案,因为它不是这个问题的可能答案。

标签: c# json json.net


【解决方案1】:

您可以使用自定义JsonConverter 来处理这种情况。
像这样定义你的数据类:

[JsonConverter(typeof(CustomConverter))]
public class RootObject
{
    public Dictionary<string, Order> Orders { get; set; }
    public string RecsInDB { get; set; }
    public string RecsOnPage { get; set; }
}

public class Order
{
    [JsonProperty("orders.orderid")]
    public string OrderID { get; set; }

    [JsonProperty("entity.customerid")]
    public string CustomerID { get; set; }

    [JsonProperty("entity.entityid")]
    public string EntityID { get; set; }
}

创建一个自定义转换器来处理这样的根对象:

class CustomConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(RootObject));
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject jo = JObject.Load(reader);
        RootObject obj = new RootObject();
        obj.RecsInDB = jo["recsindb"].ToString();
        obj.RecsOnPage = jo["recsonpage"].ToString();
        obj.Orders = new Dictionary<string, Order>();
        foreach (JProperty prop in jo.Properties())
        {
            if (prop.Name != "recsindb" && prop.Name != "recsonpage")
            {
                obj.Orders.Add(prop.Name, prop.Value.ToObject<Order>());
            }
        }
        return obj;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

然后你可以像这样反序列化:

RootObject obj = JsonConvert.DeserializeObject<RootObject>(json);

现在您可以像往常一样使用数据类了。这是一个演示:

class Program
{
    static void Main(string[] args)
    {
        string json = @"
        {
            ""1"": {
                ""orders.orderid"":""538"",
                ""entity.customerid"":""109"",
                ""entity.entityid"":""538"",
            },
            ""2"": {
                ""orders.orderid"":""536"",
                ""entity.customerid"":""108"",
                ""entity.entityid"":""536"",
            },
            ""recsindb"":""2"",
            ""recsonpage"":""2""
        }";

        RootObject obj = JsonConvert.DeserializeObject<RootObject>(json);

        Console.WriteLine("RecsInDB: " + obj.RecsInDB);
        Console.WriteLine("RecsOnPage: " + obj.RecsOnPage);
        foreach (var kvp in obj.Orders)
        {
            Console.WriteLine("Order #" + kvp.Key);
            Console.WriteLine("   OrderID " + kvp.Value.OrderID);
            Console.WriteLine("   CustomerID " + kvp.Value.CustomerID);
            Console.WriteLine("   EntityID " + kvp.Value.EntityID);
        }
    }
}

输出:

RecsInDB: 2
RecsOnPage: 2
Order #1
   OrderID 538
   CustomerID 109
   EntityID 538
Order #2
   OrderID 536
   CustomerID 108
   EntityID 536

【讨论】:

  • 效果很好,谢谢。唯一不同的是,我没有让 Orders 成为 RootObject 的属性,而是从 Dictionary 继承了 RootObject,并将订单添加到 RootObject。
  • 没问题;很乐意提供帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-07-27
  • 1970-01-01
  • 1970-01-01
  • 2022-01-22
  • 1970-01-01
相关资源
最近更新 更多