【问题标题】:Can I Deserialize a specific field from JSON?我可以从 JSON 反序列化特定字段吗?
【发布时间】:2018-01-17 15:43:46
【问题描述】:

我正在编写一个采用英国邮政编码并将该邮政编码的纬度和经度作为“位置”对象返回的方法。

public class Location
{
    public double Longitude;
    public double Latitude;
}

我正在使用来自https://postcodes.io/ 的 API,它采用邮政编码并返回相当大的一组数据。例如(白金汉宫,如果你有兴趣):

{
"status": 200,
"result": {
    "postcode": "SW1A 1AA",
    "quality": 1,
    "eastings": 529090,
    "northings": 179645,
    "country": "England",
    "nhs_ha": "London",
    "longitude": -0.141587597876975,
    "latitude": 51.5010091564599,
    "european_electoral_region": "London",
    "primary_care_trust": "Westminster",
    "region": "London",
    "lsoa": "Westminster 018C",
    "msoa": "Westminster 018",
    "incode": "1AA",
    "outcode": "SW1A",
    "parliamentary_constituency": "Cities of London and Westminster",
    "admin_district": "Westminster",
    "parish": "Westminster, unparished area",
    "admin_county": null,
    "admin_ward": "St James's",
    "ccg": "NHS Central London (Westminster)",
    "nuts": "Westminster",
    "codes": {
        "admin_district": "E09000033",
        "admin_county": "E99999999",
        "admin_ward": "E05000644",
        "parish": "E43000236",
        "parliamentary_constituency": "E14000639",
        "ccg": "E38000031",
        "nuts": "UKI32"
        }
    }
}

目前,我已将其设置为通过使用 Visual Studio 的“选择性粘贴 > 将 JSON 粘贴为类”功能为数据生成类来获取数据,然后使用 JSON.Net 反序列化整个数据集,然后使用纬度和结果对象的经度来创建一个新的 Location 对象。

Rootobject locationData = JsonConvert.DeserializeObject<Rootobject>(content);

        Location locationToReturn = new Location()
        {
            Latitude = locationData.result.latitude,
            Longitude = locationData.result.longitude
        };

当我只需要两个字段时,我必须努力反序列化整个事情,这对我来说似乎很愚蠢。

所以问题是:

我可以只反序列化纬度和经度字段吗?

更具体地说,我可以将纬度和经度字段直接反序列化到我的 Location 类的新实例中吗?

【问题讨论】:

  • 如果这个问题已经得到解答,我深表歉意,但我找不到任何我认为完全符合我的情况的内容。
  • 查看反序列化为动态对象。然后你可以像这样使用它。
  • 您关心性能吗?我没有对此进行测试,但我很确定反序列化 20 个字段的额外开销不会比反序列化 2 个字段多多少。
  • 首先,让我们澄清一下我们使用的一些术语。 Newtonsoft.js 反序列化对象。 Newtonsoft 对 json 的反序列化是将一些字符串转换为 JObject 类的过程。之后,它会尝试将此 JObject 映射到您的自定义类型。因此,一种方法是直接使用 JObject 并动态访问其属性,但请记住,首先它将反序列化整个 json,因此如果有的话,性能增益将是最小的......
  • @Fabjan 谢谢,这有助于我更好地理解它。我只是在寻找一种减少不必要代码的方法,而不是任何性能提升。

标签: c# .net json json.net


【解决方案1】:

您可以将数据加载到动态对象中。 然后从那里阅读。

        dynamic locationData = JsonConvert.DeserializeObject<dynamic>(content);

        Location locationToReturn = new Location()
        {
            Latitude = locationData.result.latitude,
            Longitude = locationData.result.longitude
        };

        Console.WriteLine("Latitude: " + locationToReturn.Latitude);
        Console.WriteLine("Longitude: " + locationToReturn.Longitude);

        Console.ReadLine();

通过这种方式,您也可以获取其他列或值,而无需枚举所有字段。

【讨论】:

  • 出于多种原因,我不喜欢动态对象类型。但是这个建议只是改变了我对一个好的用例的看法!谢谢。
【解决方案2】:

你可以像这样使用JObject 做你想做的事:

Location locationData = JObject.Parse(content)["result"].ToObject<Location>();

小提琴:https://dotnetfiddle.net/vWwLUf


或者,只需更改 Rootobject 类的类定义:

class Rootobject
{
    [JsonProperty("result")]
    public Location Location { get; set; }
}

那么你可以这样做:

Location locationData = JsonConvert.DeserializeObject<Rootobject>(content).Location;

小提琴:https://dotnetfiddle.net/imng8Q

【讨论】:

    【解决方案3】:

    您可以使用 Newtonsoft.Json (Json.Net) 自己遍历 json 对象,只获取您需要的值。

    您可能希望使用 JObject 来捕获整个结果。转到result的子token,然后抓取子项的经纬度,根据需要反序列化。

    你也可以看看这个答案How do I enumerate through a JObject?

    【讨论】:

      猜你喜欢
      • 2018-06-21
      • 1970-01-01
      • 2014-04-14
      • 2011-09-11
      • 1970-01-01
      • 1970-01-01
      • 2012-07-10
      • 1970-01-01
      • 2017-09-21
      相关资源
      最近更新 更多