【问题标题】:How to pull a specific value from dynamic JSON dictionary in C#如何从 C# 中的动态 JSON 字典中提取特定值
【发布时间】:2019-12-10 04:31:58
【问题描述】:

我正在尝试从从地理编码请求接收到的 json 中提取一个特定的数据。 这不是无数听起来相似的问题的重复,因为 json 是动态的,并且具有在响应之间略有变化的非常不规则的数组,因此我无法创建要解析的模型,也无法使用键导航它名字。
这是一个响应的 json:

{  
   "Response":{  
      "MetaInfo":{  
         "Timestamp":"2019-07-28T13:23:04.898+0000"
      },
      "View":[  
         {  
            "_type":"SearchResultsViewType",
            "ViewId":0,
            "Result":[  
               {  
                  "Relevance":1.0,
                  "MatchLevel":"houseNumber",
                  "MatchQuality":{  
                     "City":1.0,
                     "Street":[  
                        0.9
                     ],
                     "HouseNumber":1.0
                  },
                  "MatchType":"pointAddress",
                  "Location":{  
                     "LocationId":"NT_Opil2LPZVRLZjlWNLJQuWB_0ITN",
                     "LocationType":"point",
                     "DisplayPosition":{  
                        "Latitude":41.88432,
                        "Longitude":-87.63877
                     },
                     "NavigationPosition":[  
                        {  
                           "Latitude":41.88449,
                           "Longitude":-87.63877
                        }
                     ],
                     "MapView":{  
                        "TopLeft":{  
                           "Latitude":41.8854442,
                           "Longitude":-87.64028
                        },
                        "BottomRight":{  
                           "Latitude":41.8831958,
                           "Longitude":-87.63726
                        }
                     },
                     "Address":{  
                        "Label":"425 W Randolph St, Chicago, IL 60606, United States",
                        "Country":"USA",
                        "State":"IL",
                        "County":"Cook",
                        "City":"Chicago",
                        "District":"West Loop",
                        "Street":"W Randolph St",
                        "HouseNumber":"425",
                        "PostalCode":"60606",
                        "AdditionalData":[  
                           {  
                              "value":"United States",
                              "key":"CountryName"
                           },
                           {  
                              "value":"Illinois",
                              "key":"StateName"
                           },
                           {  
                              "value":"Cook",
                              "key":"CountyName"
                           },
                           {  
                              "value":"N",
                              "key":"PostalCodeType"
                           }
                        ]
                     }
                  }
               }
            ]
         }
      ]
   }
}

我试图只获取 NavigationPosition 中的两个坐标。

在我开始创建一种方法以手动从未解析的字符串中提取我需要的数据的繁琐工作之前,有人有解决方案吗?有没有办法使用 foreach 或 if 语句匿名遍历 json 数组?

【问题讨论】:

  • 想到了 xpath。
  • 路径示例:newtonsoft.com/json/help/html/QueryJsonSelectTokenJsonPath.htm - 如果这看起来像是您想尝试但无法弄清楚的东西,我会为您提供一个完整的示例。让我知道。
  • 什么是动态的 json?肯定有某种逻辑结构吗?
  • 如果位置可以在任何地方,但始终使用相同的名称,您可以使用JsonTokenReader 从文档中获取它,因为它会遍历所有属性
  • 如果你真的不能依赖键名(jsonpath),那么你唯一的选择是遍历对象树并检查当前 JsonObject 是否为 {Latitude, Longtitude} 形式。但它非常容易出错,因为示例中至少还有两个具有此类签名的属性,因此我宁愿尝试在提供此类数据的服务上强制执行适当的一致模式...

标签: c# json multidimensional-array json-deserialization


【解决方案1】:

如果响应是动态的,那么一种选择是使用动态反序列化

var dynamicObject = JsonConvert.DeserializeObject<dynamic>(jsonAsString);

您可以通过检查 null 来迭代此对象并编写防御性代码。 我假设“NavigationPosition”将始终位于“位置”下,然后位于“视图”列表下的“结果”列表下

类似这样的东西..(符号代码)

if(dynamicObject.View != null && dynamicObject.View[0] != null && dynamicObject.View[0].Result[0] != null && dynamicObject.View[0].Result[0].Location != null  )
{
    var navigationPosition = dynamicObject.View[0].Result[0].Location.NavigationPosition;
    // do something with it
}

这看起来真的很麻烦,但如果你无法控制 json 响应,我认为你应该能够在一些迭代后立即得到它:)

【讨论】:

  • 更改 if 语句以使用空条件运算符: if(dynamicObject.View?.FirstOrDefault()?.Result?.FirstOrDefault()?.Location != null) 更容易阅读 IMO跨度>
  • 也许 OP 想要随机访问而不加载整个 JSON(如果您有大量 JSON 数据可能会出现问题)。在这种情况下,这不是正确的方法。
  • " 我也不能使用键名浏览它。" - 不要认为硬编码路径是 OP 正在寻找的答案
  • 我不喜欢这样的实现,它依赖于我不知道的结构,并且将来可能随时中断。虽然我觉得如果你别无选择,请试试这个jmespath.org/examples.html
猜你喜欢
  • 2018-08-30
  • 1970-01-01
  • 2023-01-24
  • 2020-11-10
  • 2022-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多