C# 无法从JValue转换为JObject
我有一个包含静态方法的类C# 无法从JValue转换为JObject,c#,asp.net,json,json.net,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 = ne
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
}
}
我不喜欢反序列化整个对象,因为服务不会使用几乎所有这些属性,除了
“legs”
、“steps”
、以及“end\u 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);
}
您正在调用,但此方法有多个重载,所以调用哪个重载?因为存在一个,所以发生的情况是,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();
注:
- 您可以使用从
直接反序列化到POCO。将JToken
格式化为字符串,然后反序列化字符串,这样做更简单、更高效JToken
- 允许使用查询JSON层次结构
此处,
表示一个通配符,用于选择数组中的所有项,特别是[*]
、“routes”
和“legs”
数组 有关更多信息,请参阅“steps”
Demo fiddle.“我不喜欢反序列化整个对象”-你让它变得更加困难
JObject.Parse(content)
已经在反序列化整个过程。只需遍历对象图,而不是转换回字符串并重新计算。这在我的本地机器上非常有效,我的返回模型如下:{code>[{“Legs”:[{“Steps”:[{“EndLocation”:[{“Lat”:41.0917854,“Lng”:29.0938952},{“Lat”:41.0927256,“Lng”:29.0943774},{“Lat”:41.0931956,“ln”:29.094848},{“Lat”:41.094488299988,“Lng”:29.0952805},{“Lat”:41.0945246,“Lng”:29.0954362},{“Lat”:41.0945706,“Lng”:29.0955857},{“Lat”:41.0943654999988,“Lng”:29.0967187}]}]}]但是,在我将此API项目发布到服务器并向返回此模型的方法发送相同的请求后,它返回模型而不填充EndLocation listLive项目返回此:{“Legs”:[{“步骤”:[{“EndLocation”:[]}]}]
奇怪的是,我也在另一台服务器上进行了测试,它按预期填充了模型。你知道这是怎么发生的吗?@RaZzLe-需要查看一个示例,但可能你没有将服务器配置为使用camel case?请查看或。
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; }
}