【问题标题】:C# Get specific object from JSON response using HttpClientC# 使用 HttpClient 从 JSON 响应中获取特定对象
【发布时间】:2016-06-02 15:51:37
【问题描述】:

我正在尝试从 google maps api 解析 json 以进行地理编码。

JSON 是:

{
"results" : [
  {
     "address_components" : [
        {
           "long_name" : "1600",
           "short_name" : "1600",
           "types" : [ "street_number" ]
        },
        {
           "long_name" : "Amphitheatre Parkway",
           "short_name" : "Amphitheatre Pkwy",
           "types" : [ "route" ]
        },
        {
           "long_name" : "Mountain View",
           "short_name" : "Mountain View",
           "types" : [ "locality", "political" ]
        },
        {
           "long_name" : "Santa Clara County",
           "short_name" : "Santa Clara County",
           "types" : [ "administrative_area_level_2", "political" ]
        },
        {
           "long_name" : "California",
           "short_name" : "CA",
           "types" : [ "administrative_area_level_1", "political" ]
        },
        {
           "long_name" : "United States",
           "short_name" : "US",
           "types" : [ "country", "political" ]
        },
        {
           "long_name" : "94043",
           "short_name" : "94043",
           "types" : [ "postal_code" ]
        }
     ],
     "formatted_address" : "1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA",
     "geometry" : {
        "location" : {
           "lat" : 37.4224277,
           "lng" : -122.0843288
        },
        "location_type" : "ROOFTOP",
        "viewport" : {
           "northeast" : {
              "lat" : 37.4237766802915,
              "lng" : -122.0829798197085
           },
           "southwest" : {
              "lat" : 37.4210787197085,
              "lng" : -122.0856777802915
           }
        }
     },
     "place_id" : "ChIJ2eUgeAK6j4ARbn5u_wAGqWA",
     "types" : [ "street_address" ]
  }
 ],
"status" : "OK"
}

我只对具有纬度和经度的 location 对象感兴趣,并且想知道如何在 c# 中导航 json 对象树以从 HttpContent 中检索它们作为来自 HttpClient 上的 GetAsync 的响应。 以下代码片段说明了我的请求是如何完成的。

public async Task<Coordinates> GeoCode(string address) 
{
      HttpClient client= new HttpClient();
      var baseUrl = "http://maps.google.com/maps/api/geocode/json?address=";
      var addressEncoded = WebUtility.UrlEncode(address);
      var response= await client.GetAsync(baseUrl + addressEncoded);

      if(response.IsSuccessStatusCode)
      {
           //read location ...
      }
}

如何读取位置对象?

【问题讨论】:

    标签: c# json parsing httpclient


    【解决方案1】:

    这是我通常的做法。 (我将你的 json 对象保存到 D:/json.txt)

     var json = File.ReadAllText("D:/json.txt");
     var results = JObject.Parse(json).SelectToken("results") as JArray;
    
    foreach (var result in results)
    {
        var geometryEntry = result.SelectToken("geometry.location");
        var longitude = geometryEntry.Value<double>("lat");
        var latitude = geometryEntry.Value<double>("lng");
    
        Console.WriteLine("{0}, {1}", longitude, latitude);
    }
    

    输出:

    【讨论】:

      【解决方案2】:

      一种选择是将 JSON 反序列化为类型化类和其他使用 动态 类型。

      Using JSON.NET for dynamic JSON parsing

      JSON 字符串表示具有三个属性的对象,该对象被解析为 JObject 类并转换为动态。一旦转换为动态,我就可以继续使用熟悉的对象语法访问对象。

      public void JValueParsingTest()
      {
          var jsonString = @"{""Name"":""Rick"",""Company"":""West Wind"",
                              ""Entered"":""2012-03-16T00:03:33.245-10:00""}";
      
          dynamic json = JValue.Parse(jsonString);
      
          // values require casting
          string name = json.Name;
          string company = json.Company;
          DateTime entered = json.Entered;
      
          Assert.AreEqual(name, "Rick");
          Assert.AreEqual(company, "West Wind");            
      }
      

      【讨论】:

      • 谢谢,动态解决方案看起来很有趣,知道如何从 response.content 解析为动态吗?
      • 只需使用 response.Content.ReadAsStringAsync() 获取 json 作为 System.String 并将其传递给 Parse 方法。
      【解决方案3】:

      作为一种选择,您可以使用Geocoding 包提供的强类型对象来检索坐标:

      public async Task<Coordinates> GeoCode(string address) 
      {
          GoogleGeocoder geocoder = new GoogleGeocoder();
          IEnumerable<GoogleAddress> addresses = await geocoder.GeocodeAsync(address);    
      
          GoogleAddress first = addresses?.FirstOrDefault();
      
          return first == null
              ? null
              : new Coordinates
              {
                  Latitude = first.Coordinates.Latitude,
                  Longitude = first.Coordinates.Longitude
              };
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-07
        • 2016-12-20
        • 1970-01-01
        • 2017-07-03
        • 2020-11-14
        • 2017-11-22
        相关资源
        最近更新 更多