Json.NET(Newtonsoft.Json) - 两个同名的“属性”?

时间:2010-10-06 23:02:39

标签: json properties duplicates json.net

我正在使用C#编写.NET Framework 3.5。

我正在尝试将一些Json解析为JObject。

Json如下:

{
    "TBox": {
        "Name": "SmallBox",
        "Length": 1,
        "Width": 1,
        "Height": 2 },
    "TBox": {
        "Name": "MedBox",
        "Length": 5,
        "Width": 10,
        "Height": 10 },
    "TBox": {
        "Name": "LargeBox",
        "Length": 20,
        "Width": 20,
        "Height": 10 }
}

当我尝试将这个Json解析为JObject时,JObject只知道LargeBox。 SmallBox和MedBox的信息丢失了。显然这是因为它将“TBox”解释为属性,并且该属性被覆盖。

我从一个用Delphi编码的服务收到这个Json。我正在尝试为该服务创建一个C#代理。在Delphi方面,“TBox”被理解为被返回对象的类型。然后将内部属性(“名称”,“长度”,“宽度”,“高度”)理解为常规属性。

我可以序列化和反序列化具有Name,Length,Width和Height属性的自定义'TBox'对象。没关系。

我想要做的是逐步浏览所有TBox部分,以便提取以下三个Json字符串。

首先:

{
    "Name": "SmallBox",
    "Length": 1,
    "Width": 1,
    "Height": 2 }

第二

{
    "Name": "MedBox"
    "Length": 5,
    "Width": 10,
    "Height": 10 }

第三

{
    "Name": "LargeBox"
    "Length": 20,
    "Width": 20,
    "Height": 10 }

一旦我掌握了这些字符串,我就可以将我的内容序列化和反序列化。

我发现Newtonsoft.Json非常好。如果我能避免它,我真的不想搞乱其他框架。

非常感谢任何帮助。

关于可以对服务器进行的更改,我的输入非常有限。

2 个答案:

答案 0 :(得分:8)

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

JsonTextReader jsonReader = new JsonTextReader(reader);
jsonReader.Read();
while(jsonReader.Read())
{
    if(jsonReader.TokenType == JsonToken.StartObject)
    {
        JObject tbox = JObject.Load(jsonReader);
    }
}

但是,请注意RFC说“对象中的名称应该是唯一的”,所以如果可以的话,建议更改格式。

编辑:这是一个没有重复键的替代设计:

[
    {
        "TBox": {
            "Width": 1,
            "Length": 1,
            "Name": "SmallBox",
            "Height": 2
        }
    },
    {
        "TBox": {
            "Width": 10,
            "Length": 5,
            "Name": "MedBox",
            "Height": 10
        }
    },
    {
        "TBox": {
            "Width": 20,
            "Length": 20,
            "Name": "LargeBox",
            "Height": 10
        }
    }
]

答案 1 :(得分:3)

如果我没有弄错的话,对此的正确答案是你的输入实际上不是JSON。所以不,获得一个JSON解析器来解析它可能不会起作用。

也许你对输入源没有任何控制权,所以我会使用正则表达式或其他东西来预先过滤字符串。把它变成类似的东西:

{"TBoxes":
    [
        {
            "Name": "SmallBox",
            "Length": 1,
            "Width": 1,
            "Height": 2 
        },
        {
            "Name": "MedBox",
            "Length": 5,
            "Width": 10,
            "Height": 10 
        },
        {
            "Name": "LargeBox",
            "Length": 20,
            "Width": 20,
            "Height": 10 
        }
    ]
}

并将其视为数组。