解析HttpResponse中的单个值

时间:2018-09-18 00:27:57

标签: c# json http

在调用Google Geolocation API时,返回的结果(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
           },

我需要从返回的数据中检索各种各样的单个项目,例如duration:text值。 有没有办法过滤掉API调用中的多余信息,或者如何从Json解析出来?

我尝试反序列化一个对象,然后对其进行迭代并获取legs数组,但是A.无效,因为该对象位于大型项目上,而不是集合上,而B.看来很浪费。

 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

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

关注

我在序列化调用后添加了.Result     response.Content.ReadAsStringAsync().Result()

现在返回正确的json

Json Returned

现在我该如何解析单个值,或者可以反序列化为Duration类。 根据查尔斯的建议

我有一个根对象

公共类MapsDirectionObject     {         public GeocodedWaypoints [] geocoded_waypoints {get;组; }         public Routes []条路线{get;组; }     }

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; }
}

由于返回的json只有两个主要子级,即路线和航路点,因此我也具有这些类。反序列化错误,并显示以下错误。

  

Newtonsoft.Json.JsonSerializationException:'转换值“ {” geocoded_waypoints“时出错:[         {

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

enter image description here

2 个答案:

答案 0 :(得分:1)

首先,请在您的答案上发布一个完整的有效JSON对象。

您使用Visual Studio进行编码吗?您可以使用特殊粘贴来帮助您:

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

2)在Visual Studio上打开您的类文件;

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;

如果需要,可以将 Rootobject 重命名为所需的任何名称,例如 Geolocation

答案 1 :(得分:1)

首先,我希望我们进行强类型的反序列化,所以让我们创建与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字符串