代码之家  ›  专栏  ›  技术社区  ›  Fabricio Rodriguez

json反序列化对象只获取前两个元素

  •  0
  • Fabricio Rodriguez  · 技术社区  · 7 年前

    在C类中,我试图反序列化从Google Place自动完成API获得的JSON字符串( https://maps.googleapis.com/maps/api/place/autocomplete/output?parameters )中。

    json如下所示:

    {
       "predictions" : [
          {
             "description" : "11 Sukhumvit Road, Khlong Toei, Bangkok, Thailand",
             "id" : "ca5d46b0982d28ee26c0aa2e94785688cff38357",
             "matched_substrings" : [
                {
                   "length" : 2,
                   "offset" : 0
                },
                {
                   "length" : 2,
                   "offset" : 3
                }
             ],
             "place_id" : "ChIJa68zyuae4jAR11FuV_P2eh4",
             "reference" : "CoQBcwAAAMWiPU84BlqBn84vF-fg3RPvBxYUWuSVpQ9QQuQy7mVLU1Z68z-4GZyfXqS8NGiTZ0OcG4VdSUKYbA-7rOdIdeixd6i2i_fxzUg_pwui61Tm82zdYV22JLYKeuuBh77iQ36GII9AWhKQzFYIeMR3W1PvdiQihpjalJIT9u3tNhH9EhAqh48JGeGZDrLGDzHvPQPrGhTvSTqfGzX5H_j7XpP6RptgsWbyKA",
             "structured_formatting" : {
                "main_text" : "11 Sukhumvit Road",
                "main_text_matched_substrings" : [
                   {
                      "length" : 2,
                      "offset" : 0
                   },
                   {
                      "length" : 2,
                      "offset" : 3
                   }
                ],
                "secondary_text" : "Khlong Toei, Bangkok, Thailand"
             },
             "terms" : [
                {
                   "offset" : 0,
                   "value" : "11"
                },
                {
                   "offset" : 3,
                   "value" : "Sukhumvit Road"
                },
                {
                   "offset" : 19,
                   "value" : "Khlong Toei"
                },
                {
                   "offset" : 32,
                   "value" : "Bangkok"
                },
                {
                   "offset" : 41,
                   "value" : "Thailand"
                }
             ],
             "types" : [ "street_address", "geocode" ]
          },
          {
             "description" : "11 Sukhumvit Road, Khlong Toei Nuea, Watthana, Bangkok, Thailand",
             "id" : "14aa9ff6b7d97031a4722e3ea0bfb71db1f5e718",
             "matched_substrings" : [
                {
                   "length" : 2,
                   "offset" : 0
                },
                {
                   "length" : 2,
                   "offset" : 3
                }
             ],
             "place_id" : "ChIJ2Rp_B_2e4jAR5kGy-6xSlmM",
             "reference" : "CpQBgwAAAFKqcxX6_22KbMz8NrEelwf76VZ4FfrJDJhnIEsoi5Pvy6hAuq8rNri1Bcp4amObhNxOa20EMSc4F82mHCzh3d3XSI0C04ERlael6zn71QnwraPmML5VpUuVJT3_pd-SrSwzFtQ-ekJIHJ62Nr42JM2HUO06JVKRWCdn9ZTFItgHT7LsjsExS0riUj3HXIzKjxIQqBO8Iysg1LkSUw6qaUMEQhoUZFSQeIa8z_qeEF39Af0SLV_MWy0",
             "structured_formatting" : {
                "main_text" : "11 Sukhumvit Road",
                "main_text_matched_substrings" : [
                   {
                      "length" : 2,
                      "offset" : 0
                   },
                   {
                      "length" : 2,
                      "offset" : 3
                   }
                ],
                "secondary_text" : "Khlong Toei Nuea, Watthana, Bangkok, Thailand"
             },
             "terms" : [
                {
                   "offset" : 0,
                   "value" : "11"
                },
                {
                   "offset" : 3,
                   "value" : "Sukhumvit Road"
                },
                {
                   "offset" : 19,
                   "value" : "Khlong Toei Nuea"
                },
                {
                   "offset" : 37,
                   "value" : "Watthana"
                },
                {
                   "offset" : 47,
                   "value" : "Bangkok"
                },
                {
                   "offset" : 56,
                   "value" : "Thailand"
                }
             ],
             "types" : [ "street_address", "geocode" ]
          },
          {
             "description" : "11 Sukhumvit Alley, Khlong Tan Nuea, Watthana, Bangkok, Thailand",
             "id" : "232f132abc93383477f9c3db792a064ce52ca026",
             "matched_substrings" : [
                {
                   "length" : 2,
                   "offset" : 0
                },
                {
                   "length" : 2,
                   "offset" : 3
                }
             ],
             "place_id" : "ChIJPR10XTWe4jARztw9WrjPuA8",
             "reference" : "CpQBgwAAALdNIHByCxKkyKPlVQUGObR_b_iHimkMzCgWSvd_G87jwMsft34B4PKYtTMRsLDdMuw7G2bMma_hiHvazg8I63qDYoNCH_GLQn6e9VkHaHvvcGtXsnglkvP2LVDfK_CCzAhtB537S05y7k5_5hpquG4MhzATqAGUhSQ9QBHw8mfaG30WNuJNrptWlcr27gH3LRIQYZ5rX2MGoVb3lwkw40jm3BoU6JlknjT6CTGWBLQnIzgfyKQphi0",
             "structured_formatting" : {
                "main_text" : "11 Sukhumvit Alley",
                "main_text_matched_substrings" : [
                   {
                      "length" : 2,
                      "offset" : 0
                   },
                   {
                      "length" : 2,
                      "offset" : 3
                   }
                ],
                "secondary_text" : "Khlong Tan Nuea, Watthana, Bangkok, Thailand"
             },
             "terms" : [
                {
                   "offset" : 0,
                   "value" : "11"
                },
                {
                   "offset" : 3,
                   "value" : "Sukhumvit Alley"
                },
                {
                   "offset" : 20,
                   "value" : "Khlong Tan Nuea"
                },
                {
                   "offset" : 37,
                   "value" : "Watthana"
                },
                {
                   "offset" : 47,
                   "value" : "Bangkok"
                },
                {
                   "offset" : 56,
                   "value" : "Thailand"
                }
             ],
             "types" : [ "street_address", "geocode" ]
          },
          {
             "description" : "11, Netaji Subhash Marg, Dariya Ganj, New Delhi, Delhi, India",
             "id" : "55e3234dcff96c3dc1fee533d5b1a360c5e228a2",
             "matched_substrings" : [
                {
                   "length" : 2,
                   "offset" : 0
                },
                {
                   "length" : 2,
                   "offset" : 11
                }
             ],
             "place_id" : "ChIJPwQlCiD9DDkR2ermrNsq4m8",
             "reference" : "CoQBfwAAAIsyxBsZzJLM5JUm6H_r_imzC-7NgVxN8ZQCORVMTHE3crhQjBheH5Hq2jzpe1UitduWJYKoPG9hVD9diwx3daMPumSwHosJvA_0MzVtBLuo-f0SgS9wbBqBpWtLZ-oCy6AzQJac190_1wy3sI6mYlRdUVDEmQkzyW92sRWfqR8_EhBY7Cb8oiDXCUtm5QqfkIu9GhSznlDT1_7dklnqyGe1hSPgP37JOA",
             "structured_formatting" : {
                "main_text" : "11, Netaji Subhash Marg",
                "main_text_matched_substrings" : [
                   {
                      "length" : 2,
                      "offset" : 0
                   },
                   {
                      "length" : 2,
                      "offset" : 11
                   }
                ],
                "secondary_text" : "Dariya Ganj, New Delhi, Delhi, India"
             },
             "terms" : [
                {
                   "offset" : 0,
                   "value" : "11"
                },
                {
                   "offset" : 4,
                   "value" : "Netaji Subhash Marg"
                },
                {
                   "offset" : 25,
                   "value" : "Dariya Ganj"
                },
                {
                   "offset" : 38,
                   "value" : "New Delhi"
                },
                {
                   "offset" : 49,
                   "value" : "Delhi"
                },
                {
                   "offset" : 56,
                   "value" : "India"
                }
             ],
             "types" : [ "street_address", "geocode" ]
          },
          {
             "description" : "11 Charan Sanitwong Road, Bang Ao, Bang Phlat, Bangkok, Thailand",
             "id" : "2bdd14e344854148907b4dd5eeed92db76c780c8",
             "matched_substrings" : [
                {
                   "length" : 2,
                   "offset" : 0
                }
             ],
             "place_id" : "ChIJ6RiwusKb4jARnKT4ah2YlHo",
             "reference" : "CpQBgwAAABENThY5H5mVwiWidokHm3bz-z-rkRoch04vGIKZV6fhSEe4fs4EX2qYPfzJw7HMDjfItx7Dlz0lGtShu5Sot3WELkz4U8PdclUfrSpMcB1jYjVIfUlYGVBdrKP0k6T-XwLSt3VCOXYFVd4lOcEvq-5Dwfcy9RstwenOXXWHHueI3PH6H-wBYFSEmJKY2Sg7ghIQg14EpHqs9If1hO-Khv4tsxoU_a-1az6q5a1VnWAZtJPvZsS4sNc",
             "structured_formatting" : {
                "main_text" : "11 Charan Sanitwong Road",
                "main_text_matched_substrings" : [
                   {
                      "length" : 2,
                      "offset" : 0
                   }
                ],
                "secondary_text" : "Bang Ao, Bang Phlat, Bangkok, Thailand"
             },
             "terms" : [
                {
                   "offset" : 0,
                   "value" : "11"
                },
                {
                   "offset" : 3,
                   "value" : "Charan Sanitwong Road"
                },
                {
                   "offset" : 26,
                   "value" : "Bang Ao"
                },
                {
                   "offset" : 35,
                   "value" : "Bang Phlat"
                },
                {
                   "offset" : 47,
                   "value" : "Bangkok"
                },
                {
                   "offset" : 56,
                   "value" : "Thailand"
                }
             ],
             "types" : [ "street_address", "geocode" ]
          }
       ],
       "status" : "OK"
    }
    

    当我运行以下命令时:

    using Newtonsoft.Json.Linq;
    JObject jObj = (JObject)JsonConvert.DeserializeObject(content);
    Debug.Write(jObj.Count);
    

    count的值为2,正如您在JSON文件中看到的,它有5个子元素。这是为什么?

    (我正在尝试为google maps places创建一个winforms自动完成文本框)

    2 回复  |  直到 7 年前
        1
  •  4
  •   Brian Rogers    7 年前

    因为外部对象有两个属性,“预测”和“状态”。您正在查看外部对象中“预测”数组的元素。请改为:

    JObject jObj = (JObject)JsonConvert.DeserializeObject(content);
    JArray predictions = (JArray)jObj["predictions"];
    Debug.Write(predictions.Count);    
    

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

        2
  •  1
  •   Brandon Minnick    7 年前

    反序列化json最完整的方法是创建 GooglePlaceModel 类,该类包含来自json响应的所有属性。

    一旦添加了googleplacemodel,就可以使用 JsonConvert.DeserializeObject 转换json string 给一个 谷歌PlaceModel

    反序列化json

    public GooglePlaceModel DeserializeGooglePlaceJson(string json)
    {
        return JsonConvert.DeserializeObject<GooglePlaceModel>(json);
    } 
    

    谷歌PlaceModel

    using System;
    using System.Collections.Generic;
    using System.Globalization;
    
    using Newtonsoft.Json;
    using Newtonsoft.Json.Converters;
    
    public class GooglePlaceModel
    {
        [JsonProperty("predictions")]
        public List<Prediction> Predictions { get; set; }
    
        [JsonProperty("status")]
        public string Status { get; set; }
    }
    
    public class Prediction
    {
        [JsonProperty("description")]
        public string Description { get; set; }
    
        [JsonProperty("id")]
        public string Id { get; set; }
    
        [JsonProperty("matched_substrings")]
        public List<MatchedSubstring> MatchedSubstrings { get; set; }
    
        [JsonProperty("place_id")]
        public string PlaceId { get; set; }
    
        [JsonProperty("reference")]
        public string Reference { get; set; }
    
        [JsonProperty("structured_formatting")]
        public StructuredFormatting StructuredFormatting { get; set; }
    
        [JsonProperty("terms")]
        public List<Term> Terms { get; set; }
    
        [JsonProperty("types")]
        public List<TypeElement> Types { get; set; }
    }
    
    public class MatchedSubstring
    {
        [JsonProperty("length")]
        public long Length { get; set; }
    
        [JsonProperty("offset")]
        public long Offset { get; set; }
    }
    
    public class StructuredFormatting
    {
        [JsonProperty("main_text")]
        public string MainText { get; set; }
    
        [JsonProperty("main_text_matched_substrings")]
        public List<MatchedSubstring> MainTextMatchedSubstrings { get; set; }
    
        [JsonProperty("secondary_text")]
        public string SecondaryText { get; set; }
    }
    
    public class Term
    {
        [JsonProperty("offset")]
        public long Offset { get; set; }
    
        [JsonProperty("value")]
        public string Value { get; set; }
    }
    
    public enum TypeElement { Geocode, StreetAddress };
    
    internal static class Converter
    {
        public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
        {
            MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
            DateParseHandling = DateParseHandling.None,
            Converters = {
                TypeElementConverter.Singleton,
                new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
            },
        };
    }
    
    internal class TypeElementConverter : JsonConverter
    {
        public override bool CanConvert(Type t) => t == typeof(TypeElement) || t == typeof(TypeElement?);
    
        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.Null) return null;
            var value = serializer.Deserialize<string>(reader);
            switch (value)
            {
                case "geocode":
                    return TypeElement.Geocode;
                case "street_address":
                    return TypeElement.StreetAddress;
            }
            throw new Exception("Cannot unmarshal type TypeElement");
        }
    
        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
        {
            if (untypedValue == null)
            {
                serializer.Serialize(writer, null);
                return;
            }
            var value = (TypeElement)untypedValue;
            switch (value)
            {
                case TypeElement.Geocode:
                    serializer.Serialize(writer, "geocode");
                    return;
                case TypeElement.StreetAddress:
                    serializer.Serialize(writer, "street_address");
                    return;
            }
            throw new Exception("Cannot marshal type TypeElement");
        }
    
        public static readonly TypeElementConverter Singleton = new TypeElementConverter();
    }
    

    googleplacemodel的来源: https://app.quicktype.io