c# - 无法从 JValue 转换为 JObject

标签 c# asp.net json json.net

我有下面的类,其中有一个静态方法,

public static class RouteSerializer
{
    public static string SerializeRouteInformation(string content)
    {
        RouteMapModel routeMapModel = new RouteMapModel();
        List<RouteMapModel.end_location> endLocationList = new List<RouteMapModel.end_location>();

        var obj = JObject.Parse(content);

        string objRoutes = obj["routes"].ToString();

        JArray routeArray = JArray.Parse(objRoutes);

        JArray legArray = new JArray();
        foreach (JObject item in routeArray)
        {
            string leg = item.GetValue("legs").ToString();                
            legArray.Add(leg);
        }

        JArray stepArray = new JArray();
        foreach (JObject item in legArray)
        {
            string step = item.GetValue("steps").ToString();
            stepArray.Add(step);
        }

        foreach(JObject item in stepArray)
        {
            string endLocation = item.GetValue("end_location").ToString();
            var serializedEndLocation = JsonConvert.DeserializeObject<RouteMapModel.end_location>(endLocation);
            endLocationList.Add(serializedEndLocation);
        }

        //... goes on
    }
}

但是,我在请求第二个 foreach 时遇到错误,因为它说 Newtonsoft.Json.Linq.JValue cannot be assigned to Newtonsoft.Json.Linq.JObject。但问题是,如果我在后面的 foreach 子句上将项目类型从 JObject 更改为 JValue,我将无法访问 .GetValue() 方法,因为 JValue 没有包括一个。

下面是我正在播放的 JSON 字符串,

    { "geocoded_waypoints" : [
      {
         "geocoder_status" : "OK",
         "place_id" : "ChIJ5cGzCGa4yhQRk-lsJUoyizk",
         "types" : [ "street_address" ]
      },
      {
         "geocoder_status" : "OK",
         "place_id" : "ChIJb5VnEF64yhQRCrgps2g77jc",
         "types" : [ "street_address" ]
      }
   ],
"routes" : [
      {
         "bounds" : {
            "northeast" : {
               "lat" : 40.990381,
               "lng" : 29.0282547
            },
            "southwest" : {
               "lat" : 40.9863897,
               "lng" : 29.0216118
            }
         },
         "copyrights" : "Harita verileri ©2019 Google",
         "legs" : [
            {
               "distance" : {
                  "text" : "0,9 km",
                  "value" : 894
               },
               "duration" : {
                  "text" : "11 dakika",
                  "value" : 655
               },
               "end_address" : "Caferağa Mahallesi, Tuğlacı Eminbey Cd. No:5, 34710 Kadıköy/İstanbul, Türkiye",
               "end_location" : {
                  "lat" : 40.9863897,
                  "lng" : 29.0218105
               },
               "start_address" : "Osmanağa Mahallesi, Serasker Cd. No:118, 34714 Kadıköy/İstanbul, Türkiye",
               "start_location" : {
                  "lat" : 40.9893375,
                  "lng" : 29.028225
               },
               "steps" : [
                  {
                     "distance" : {
                        "text" : "8 m",
                        "value" : 8
                     },
                     "duration" : {
                        "text" : "1 dakika",
                        "value" : 5
                     },
                     "end_location" : {
                        "lat" : 40.9894537,
                        "lng" : 29.0282117
                     },
                     "html_instructions" : "\u003cb\u003eZiya Bey Sk.\u003c/b\u003e adlı yerden \u003cb\u003eSerasker Cd.\u003c/b\u003e hedefine \u003cb\u003ekuzey\u003c/b\u003e yönünde ilerleyin",
                     "polyline" : {
                        "points" : "kvdyFkqdpDGCMA?F"
                     },
                     "start_location" : {
                        "lat" : 40.9893375,
                        "lng" : 29.028225
                     },
                     "travel_mode" : "WALKING"
                  },
                  {
                     "distance" : {
                        "text" : "0,3 km",
                        "value" : 326
                     },
                     "duration" : {
                        "text" : "4 dakika",
                        "value" : 215
                     },
                     "end_location" : {
                        "lat" : 40.990381,
                        "lng" : 29.024582
                     },
                     "html_instructions" : "\u003cb\u003eSerasker Cd.\u003c/b\u003e yönünde \u003cb\u003esola\u003c/b\u003e dönün",
                     "maneuver" : "turn-left",
                     "polyline" : {
                        "points" : "awdyFiqdpDMxAKr@OjACP[vCEPC^Cf@CLAHENMZ@LQf@Qd@KZENSj@"
                     },
                     "start_location" : {
                        "lat" : 40.9894537,
                        "lng" : 29.0282117
                     },
                     "travel_mode" : "WALKING"
                  },
                  {
                     "distance" : {
                        "text" : "34 m",
                        "value" : 34
                     },
                     "duration" : {
                        "text" : "1 dakika",
                        "value" : 25
                     },
                     "end_location" : {
                        "lat" : 40.9901185,
                        "lng" : 29.0243691
                     },
                     "html_instructions" : "\u003cb\u003eMühürdar Cd.\u003c/b\u003e yönünde \u003cb\u003esola\u003c/b\u003e dönün",
                     "maneuver" : "turn-left",
                     "polyline" : {
                        "points" : "{|dyFszcpDHFHF^X"
                     },
                     "start_location" : {
                        "lat" : 40.990381,
                        "lng" : 29.024582
                     },
                     "travel_mode" : "WALKING"
                  },
                  {
                     "distance" : {
                        "text" : "8 m",
                        "value" : 8
                     },
                     "duration" : {
                        "text" : "1 dakika",
                        "value" : 5
                     },
                     "end_location" : {
                        "lat" : 40.990081,
                        "lng" : 29.0242851
                     },
                     "html_instructions" : "\u003cb\u003eMühürdar Cd.\u003c/b\u003e yönünde hafif \u003cb\u003esağa\u003c/b\u003e yönelin",
                     "maneuver" : "turn-slight-right",
                     "polyline" : {
                        "points" : "g{dyFiycpD?D?@?@@??@DB"
                     },
                     "start_location" : {
                        "lat" : 40.9901185,
                        "lng" : 29.0243691
                     },
                     "travel_mode" : "WALKING"
                  },
                  {
                     "distance" : {
                        "text" : "7 m",
                        "value" : 7
                     },
                     "duration" : {
                        "text" : "1 dakika",
                        "value" : 6
                     },
                     "end_location" : {
                        "lat" : 40.9900274,
                        "lng" : 29.0243112
                     },
                     "html_instructions" : "\u003cb\u003eMuvakkıthane Cd.\u003c/b\u003e konumunda \u003cb\u003esola\u003c/b\u003e dönün",
                     "maneuver" : "turn-left",
                     "polyline" : {
                        "points" : "_{dyFyxcpDDABA"
                     },
                     "start_location" : {
                        "lat" : 40.990081,
                        "lng" : 29.0242851
                     },
                     "travel_mode" : "WALKING"
                  },
                  {
                     "distance" : {
                        "text" : "0,4 km",
                        "value" : 352
                     },
                     "duration" : {
                        "text" : "4 dakika",
                        "value" : 259
                     },
                     "end_location" : {
                        "lat" : 40.987586,
                        "lng" : 29.0217648
                     },
                     "html_instructions" : "\u003cb\u003eMühürdar Cd.\u003c/b\u003e yönünde \u003cb\u003esağa\u003c/b\u003e dönün",
                     "maneuver" : "turn-right",
                     "polyline" : {
                        "points" : "uzdyF}xcpDhAz@pA|@pBtAHRJHRPPNPX\\d@BDHKfAlBDLDHDN@LBN"
                     },
                     "start_location" : {
                        "lat" : 40.9900274,
                        "lng" : 29.0243112
                     },
                     "travel_mode" : "WALKING"
                  },
                  {
                     "distance" : {
                        "text" : "63 m",
                        "value" : 63
                     },
                     "duration" : {
                        "text" : "1 dakika",
                        "value" : 51
                     },
                     "end_location" : {
                        "lat" : 40.987087,
                        "lng" : 29.0216118
                     },
                     "html_instructions" : "\u003cb\u003eMühürdar Cd.\u003c/b\u003e boyunca ilerlemek için \u003cb\u003esola\u003c/b\u003e dönün",
                     "maneuver" : "turn-left",
                     "polyline" : {
                        "points" : "mkdyF_icpDNBJ@J@TBJ?JADA@DDN"
                     },
                     "start_location" : {
                        "lat" : 40.987586,
                        "lng" : 29.0217648
                     },
                     "travel_mode" : "WALKING"
                  },
                  {
                     "distance" : {
                        "text" : "74 m",
                        "value" : 74
                     },
                     "duration" : {
                        "text" : "1 dakika",
                        "value" : 64
                     },
                     "end_location" : {
                        "lat" : 40.9864708,
                        "lng" : 29.0216118
                     },
                     "html_instructions" : "\u003cb\u003eMühürdar Cd.\u003c/b\u003e boyunca ilerlemek için \u003cb\u003esola\u003c/b\u003e dönün",
                     "maneuver" : "turn-left",
                     "polyline" : {
                        "points" : "ihdyFahcpDJEJAFALAH?VBj@F"
                     },
                     "start_location" : {
                        "lat" : 40.987087,
                        "lng" : 29.0216118
                     },
                     "travel_mode" : "WALKING"
                  },
                  {
                     "distance" : {
                        "text" : "22 m",
                        "value" : 22
                     },
                     "duration" : {
                        "text" : "1 dakika",
                        "value" : 25
                     },
                     "end_location" : {
                        "lat" : 40.9863897,
                        "lng" : 29.0218105
                     },
                     "html_instructions" : "\u003cb\u003eTuğlacı Eminbey Cd.\u003c/b\u003e yönünde \u003cb\u003esola\u003c/b\u003e dönün",
                     "maneuver" : "turn-left",
                     "polyline" : {
                        "points" : "mddyFahcpDNg@"
                     },
                     "start_location" : {
                        "lat" : 40.9864708,
                        "lng" : 29.0216118
                     },
                     "travel_mode" : "WALKING"
                  }
               ],
               "traffic_speed_entry" : [],
               "via_waypoint" : []
            }
         ],
         "overview_polyline" : {
            "points" : "kvdyFkqdpDUEM`B{@hHQfBGXMZ@Lc@lAQj@Sj@HFHF^X?D?B@@DBDABAhAz@bErCHRJHd@`@n@~@BDHKlAzBJXD\\ZD`@DVADA@DDNJERCVAbAJNg@"
         },
         "summary" : "Serasker Cd. ve Mühürdar Cd.",
         "warnings" : [
            "Yürüyerek gitmek için yol tarifi beta özelliğinde mevcuttur. Dikkat – Bu rotada kaldırım veya yaya yolu olmayabilir."
         ],
         "waypoint_order" : []
      }
   ],
   "status" : "OK"
}

我不喜欢反序列化整个对象,因为服务不会使用几乎所有这些属性,除了 "legs""steps" “end_location” 位于 “steps” 内。

最佳答案

问题 是您的代码查询 JObject obj 的选定部分层次结构反复从 JToken 来回转换到 JSON 字符串表示形式,并且在某一时刻,无需重新解析 JSON 字符串,您只需将其用作字符串文字

具体来说,问题在于以下代码:

JArray legArray = new JArray();
foreach (JObject item in routeArray)
{
    string leg = item.GetValue("legs").ToString();
    legArray.Add(leg);
}

您正在调用 JArray.Add() ,但是这个方法有多个重载,那么调用哪个呢?因为有一个 implicit operator from string to JToken , 发生的是 leg字符串被转换为 JValue使用隐式运算符的字符串文字,它又被添加到 JArray .之后,以下代码因无效转换异常而失败,因为您添加到 legArray 的项目类型为 JValue不是JObject :

foreach (JObject item in legArray)
{

解决方案是简化您的代码并完全避免在string 之间来回转换。和 JToken交涉。以下代码可以解决问题:

var endLocationList = obj
    .SelectTokens("routes[*].legs[*].steps[*].end_location")
    .Select(t => t.ToObject<Location>())
    .ToList();

使用类型

public class Location
{
    public double Lat { get; set; }
    public double Lng { get; set; }
}

注意事项:

演示 fiddle here .

关于c# - 无法从 JValue 转换为 JObject,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54770959/

相关文章:

jquery - 当我有前一个索引或 id 时,有没有办法获取 json 中的下一个元素

jquery - 更改 json 值而不使用键名称

c# - 有没有更好的方法来调用 C# 中对象列表的比较?

c# - 使用 DirectShow.NET 从网络摄像头捕获帧

C# PDF 文档中的尖锐位置

c# - 如何验证电子邮件来自ASP.NET MVC中的特定域?

c# - 为什么我在保存数据库条目时得到 "unhandled exception"?

c# - HtmlEditorExtender 的回发问题

asp.net - 将 DropDownList SelectedValue 设置为有时为空值的绑定(bind)字段

arrays - 在 Swift 3 中使用嵌套数组解析 JSON