代码之家  ›  专栏  ›  技术社区  ›  dinotom

解析HttpResponse中的单个值

  •  -1
  • dinotom  · 技术社区  · 7 年前

    在调用googlegeolocationapi时,结果(json)是这样返回的

    例子 (抱歉,我无法正确格式化Json)

    {"geocoded_waypoints" : [
      {
         "geocoder_status" : "OK",
         "place_id" : "EiQ3LCA3IExha2VzaWRlIERyLCBSeWUsIE5ZIDEwNTgwLCBVU0EiHRobChYKFAoSCQH00P0vl8KJEQ2d7mWAl0jrEgE3",
         "types" : [ "subpremise" ]
      },
      {
         "geocoder_status" : "OK",
         "place_id" : "ChIJ1YqpR4eRwokRTuazxMrnKiM",
         "types" : [ "establishment", "point_of_interest" ]
      }   ],
    "routes" : [{
         "bounds" : {
            "northeast" : {
               "lat" : 41.0044903,
               "lng" : -73.6892836
            },
            "southwest" : {
               "lat" : 40.9575099,
               "lng" : -73.7589093
            }
         },
         "copyrights" : "Map data ©2018 Google",
         "legs" : [
            {
               "distance" : {
                  "text" : "7.0 mi",
                  "value" : 11325
               },
               "duration" : {
                  "text" : "15 mins",
                  "value" : 889
               },
               "end_address" : "851 Fenimore Rd, Mamaroneck, NY 10543, USA",
               "end_location" : {
                  "lat" : 40.9575099,
                  "lng" : -73.75338219999999
               },
               "start_address" : "7 Pheasant Run #7, Rye, NY 10580, USA",
               "start_location" : {
                  "lat" : 40.99850199999999,
                  "lng" : -73.689633
               },
    

    我需要从返回的数据中检索各种单个项,例如持续时间:文本值。 有没有办法过滤掉API调用中多余的内容,或者如何从Json中解析这些内容?

     public int TravelTimeInMinutes(string origin, string destination, string apiKey)
        {
            var timeToTravel = 0;
    
            var url = DirectionsUrlBase + ConvertOriginFormat(origin) + ConvertDestinationFormat(destination) + "&key="+ apiKey;
            var client = new HttpClient();
    
            // Add the Accept type header for JSON format.
            client.DefaultRequestHeaders.Accept.Add(
                new MediaTypeWithQualityHeaderValue("application/json"));
    
            // get the response
            // make method async once working
             var response = client.GetAsync(url).Result;   
            if (response.IsSuccessStatusCode)
            {
                // Parse the response body.
                var result = JsonConvert.SerializeObject(response.Content.ReadAsStringAsync().Result());
                dynamic array = JsonConvert.DeserializeObject(result);
                foreach (var item in array)
                {
    
                }
              //… rest removed for brevity
    

    如何向下钻取单个值?我认为我的错误在于我如何反序列化响应。我还有一个带有文本和值属性的Duration类。如果可能的话,我想反序列化到那个类。

    我补充道 .Result response.Content.ReadAsStringAsync().Result()

    现在返回正确的json

    Json Returned

    现在我该如何解析这个类中的单个值,或者反序列化到Duration类中。

    我有一个根对象

    公共类MapsDirectionObject { }

    public class Routes
    {
        public object[] Value { get; set; }
    }
    
    public class GeocodedWaypoints
    {
        public string geocoder_status { get; set; }
        public string place_id { get; set; }
        public string[] types { get; set; }
    }
    

    Newtonsoft.Json.JsonSerializationException异常:'转换值{“地理编码的\航路点”时出错:[

    如果删除序列化的.Result调用,我可以映射到该对象,但值为null。

    enter image description here

    2 回复  |  直到 7 年前
        1
  •  1
  •   Ahmed Sherien    7 年前

    首先,我更希望我们进行强类型反序列化,因此让我们创建与我们需要的JSON数据相对应的类:

    public class ResultData
    {
        [JsonProperty("routes")]
        public List<Route> Routes { get; set; }
    }
    
    public class Route
    {
        [JsonProperty("legs")]
        public List<Leg> Legs { get; set; }
    }
    
    public class Leg
    {
        [JsonProperty("duration")]
        public Duration Duration { get; set; }
    }
    
    public class Duration
    {
        [JsonProperty("text")]
        public string Text { get; set; }
        [JsonProperty("value")]
        public int Value { get; set; }
    }
    

    然后反序列化JSON:

    var client = new HttpClient();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    var response = client.GetAsync("https://maps.googleapis.com/maps/api/directions/json?origin=7+7+Lakeside+Dr+Rye+NY&destination=Winged+Winged+Foot+Golf+Club").Result;
    if (response.IsSuccessStatusCode)
    {
        var desed = JsonConvert.DeserializeObject<ResultData>(response.Content.ReadAsStringAsync().Result);
        var durations = desed.Routes.SelectMany(r => r.Legs.Select(l => l.Duration)).ToList();
        durations.ForEach(d => Console.WriteLine($"T: {d.Text}, V: {d.Value}"));
    }
    

    注:

    跳过序列化步骤。。。 ReadAsStringAsync() 应生成有效的JSON字符串

        2
  •  1
  •   Charles Cavalcante    7 年前

    首先,请在你的答案上贴一个完整有效的JSON对象。

    你用visualstudio编写代码,对吗?你可以用 特殊粘贴

    1) 将整个JSON复制到剪贴板;

    3) 进入“编辑”>“粘贴特殊”>“粘贴为JSON类”菜单;

    4) 你会得到这样的结果:

    public class Rootobject
    {
        public Geocoded_Waypoints[] geocoded_waypoints { get; set; }
    }
    
    public class Geocoded_Waypoints
    {
        public string geocoder_status { get; set; }
        public string place_id { get; set; }
        public string[] types { get; set; }
    }
    

    现在可以反序列化为类型化对象:

    var myObject = JsonConvert.DeserializeObject<Rootobject>(result);
    
    foreact(var geocoded_waypoints in myObject.geocoded_waypoints)
    {
        // do something with geocoded_waypoints
    }
    
    // your duration object:
    var duration = myObject.routes[0].legs[0].duration;
    

    如果你想你可以重命名 你想叫什么名字都行,比如 地理位置