Json.NET(Newtonsoft.Json)-Two';属性';同名?

Json.NET(Newtonsoft.Json)-Two';属性';同名?,json,properties,duplicates,json.net,Json,Properties,Duplicates,Json.net,我正在用C#为.NETFramework3.5编写代码 我正在尝试将一些Json解析为JObject Json如下所示: { "TBox": { "Name": "SmallBox", "Length": 1, "Width": 1, "Height": 2 }, "TBox": { "Name": "MedBox", "Length": 5, "Width": 10,

我正在用C#为.NETFramework3.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”被理解为返回的对象的类型。内部属性(“名称”、“长度”、“宽度”、“高度”)被理解为常规属性

我可以序列化和反序列化具有名称、长度、宽度和高度属性的自定义“TBox”对象。那很好

我想做的是以提取以下三个Json字符串的方式逐步遍历所有TBox部分

第一:

{
    "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非常好。如果可以避免的话,我真的不想和其他框架混在一起

任何帮助都将不胜感激

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

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);
    }
}
但是,请注意,“对象中的名称应该是唯一的”,因此如果可以,建议更改格式

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

[
    {
        "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
        }
    }
]

如果我没有弄错的话,正确的答案是您的输入实际上不是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 
        }
    ]
}

并像对待数组一样对待它。

我尝试过Regex,结果证明这很困难。在一些真实场景中,我将不得不处理对象中的对象。我尝试了一下,只是为了确定,处理嵌套的大括号和可能的字符集很快就成了一件麻烦事。我通常非常喜欢正则表达式,但在这种情况下,我希望有更简单的方法。结果表明,从技术上讲,它们仍然发送有效的Json。见我对马修的第二个评论。这对我来说很烦人,但我现在能处理。不,这真的不正确。您误解了该规范,该规范“基于JavaScript编程语言的一个子集,标准ECMA-262第三版-1999年12月。”没有JavaScript解析器会保留与多个重复键相关的最后一个值。去告诉JSON的发明者道格拉斯·克罗克福德,他错了。@Joel:错了。至少有两个。我写的和Newtonsoft提供的。仅仅因为许多解析器做出相同的无效假设并不意味着它们是错误的。他们正确地实现了规范。你不必喜欢它,但是坚持认为符合规范的东西是错误的是愚蠢的。在JSON对象中运行“执行”JS时得到的结果与什么是正确的JSON结构无关,特别是如果JSON结构不打算作为JS执行,而只是一种数据传输。结束。我对规范的解释是正确的-是你对规范的解释是错误的。规范规定名称应该是唯一的。如果它的意图是名称必须是唯一的,那么它会说它们必须是唯一的。本规范明确且有意地使用了术语“应该”,而非“必须”,并引用了定义这些术语的RFC 2119。一个应该被理解为必然的解释是不正确的解释。事实上,我从未说过它违反了RFC。但这是不直观的,我不一定同意这是打破它的理由。还有其他一些设计没有重复的键来提供类型信息。然而,由于JSON中的JS代表“JavaScript”,JavaScript数据结构不能有重复的名称,我很清楚,您的Delphi人员违反了规范的精神(如果不是字母的话)。Newtonsoft的行为完全正确,因为这与JavaScript解析器所做的相同。JSON中的对象是名称/值集合,而这个JSON误用了名称。本例中Json.NET的JObject所做的正是浏览器在提供重复属性时所做的:使用最后一个值。最好的解决方案是将JSON更改为具有类型名称属性和值属性的包装器对象,或者在值对象上添加类型作为特殊属性。冷静-我给出我的意见是为了帮助您,而不是批评您。无论如何,本例中的用户就是开发人员。开发人员习惯于使用作为名称/值集合的JSON对象。JSON主页——将它们定义为:名称/值集合。同样,您并没有违反规范,而是违反了用户(开发人员)的期望。如果你有一个很好的理由来构建JSON,那么这很好,只需注意,通过做一些非标准的事情,结果可能会有更多的问题需要JSON.Wow的消费者提供帮助。我猜你给我看的是“结束,决赛”的东西。真为你高兴。我认为json.org说Javascript解析json文本只是一种比喻。如果(语言==“JavaScript”)解析器=false?我认为JavaScript在遇到重复名称时不抛出错误不会使您关于解析器的语句无效,因为JavaScript从不解析任何内容。很好的重新定义