C# 按id使用子对象反序列化JSON
我有以下JSON:C# 按id使用子对象反序列化JSON,c#,json,xamarin,json.net,deserialization,C#,Json,Xamarin,Json.net,Deserialization,我有以下JSON: { "graph": { "edges": [{ "fromNode": "1", "toNode": "2", "distance": 200 }], "nodes": [{ "id": "1", "lat": 10.402875, "lng": 53.611151
{
"graph": {
"edges": [{
"fromNode": "1",
"toNode": "2",
"distance": 200
}],
"nodes": [{
"id": "1",
"lat": 10.402875,
"lng": 53.611151
}]
}
}
对于反序列化,我有以下类:
public class Graph {
public Node [] nodes { get; set; }
public Edge [] edges { get; set; }
}
public class Node {
public string id { get; set; }
public double lat { get; set; }
public double lng { get; set; }
}
public class Edge {
public string fromNode { get; set; }
public string toNode { get; set; }
public int distance { get; set; }
}
当我想要反序列化JSON时,我调用此函数:
JsonConvert.DeserializeObject<Graph> (content);
您是否有这样一个例子,在反序列化之后没有foreach循环?我建议您编写for Edge以返回节点:
public static class ExtensionMethods
{
public static Node FromNode(this Edge edge, Graph graph){
return graph.Nodes.FirstOrDefault(n => n.id.Equals(edge.fromNode);
}
public static Node ToNode(this Edge edge, Graph graph){
return graph.Nodes.FirstOrDefault(n => n.id.Equals(edge.toNode);
}
}
之后,您可以调用
edge.FromNode(图)
并从节点取回from。这样做的好处是,您不需要在节点类中放置检索节点的方法,也不需要从每一条边保存到图形的父关系。一种方法是编写自己的JsonConverter
(如图所示),并跟踪节点ID(例如在字典中)在反序列化过程中。然后,每次创建新的节点时,只需检索相应的边
因此,在您的自定义转换器中,您将有如下内容:
public class Edge {
public Node fromNode { get; set; }
public Node toNode { get; set; }
public int distance { get; set; }
}
public override object ReadJson(JsonReader reader, Type objectType
, object existingValue, JsonSerializer serializer)
{
Graph graph = new Graph();
List<Edge> graphEdges = new List<Edge>();
List<Node> graphNodes = new List<Node>();
Dictionnary<int, List<Edge>> fromNodesMap = new Dictionnary<int, List<Edge>>();
Dictionnary<int, List<Edge>> toNodesMap = new Dictionnary<int, List<Edge>>();
/* Parse the 'edges' array, I'm omitting the reading stuff here */
var edge = new Edge();
int fromNode = Convert.ToInt32(((JValue)obj["fromNode"]).Value);
if (fromNodesMap.Contains(fromNode)) {
fromNodesMap[fromNode].Add(edge);
} else {
var edgeList = new List<Edge>();
edgeList.Add(edge);
fromNodesMap.Add(fromNode, edgeList);
}
int toNode = Convert.ToInt32(((JValue)obj["toNode"]).Value);
if (toNodesMap.Contains(toNode)) {
toNodesMap[toNode].Add(edge);
} else {
var edgeList = new List<Edge>();
edgeList.Add(edge);
toNodesMap.Add(toNode, edgeList);
}
edge.distance = Convert.ToInt32(((JValue)obj["distance"]).Value);
graphEdges.Add(edge);
/* Parse the 'nodes' array, I'm omitting the reading stuff here */
var node = new Node();
int nodeId = Convert.ToInt32(((JValue)obj["id"]).Value);
node.lat = Convert.ToDouble(((JValue)obj["lat"]).Value);
node.lng = Convert.ToDouble(((JValue)obj["lng"]).Value);
var listEdgesSameFrom = fromNodesMap[nodeId];
foreach (var edge in listEdgesSameFrom)
edge.fromNode = node;
var listEdgesSameTo = toNodesMap[nodeId];
foreach (var edge in listEdgesSameTo)
edge.toNode = node;
graphNodes.Add(node);
/* Read till end */
graph.edges = graphEdges.ToArray();
graph.nodes = graphNodes.ToArray();
return graph;
}
public覆盖对象ReadJson(JsonReader-reader,类型objectType
,对象存在值,JsonSerializer序列化程序)
{
图形=新图形();
List graphEdges=新列表();
列表图形节点=新列表();
Dictionnary fromNodeMap=新Dictionnary();
词汇表toNodesMap=新词汇表();
/*解析'edges'数组,我省略了这里的阅读内容*/
var-edge=新边();
int fromNode=Convert.ToInt32(((JValue)obj[“fromNode”]).Value);
if(fromNodeMap.Contains(fromNode)){
FromNodeMap[fromNode]。添加(边);
}否则{
var edgeList=新列表();
边列表。添加(边);
FromNodeMap.Add(fromNode,edgeList);
}
int-toNode=Convert.ToInt32(((JValue)obj[“toNode”]).Value);
if(toNodesMap.Contains(toNode)){
toNodesMap[toNode]。添加(边);
}否则{
var edgeList=新列表();
边列表。添加(边);
添加(toNode,edgeList);
}
edge.distance=转换为32(((JValue)obj[“distance”]).Value);
添加(边);
/*解析'nodes'数组,我省略了这里的阅读内容*/
var node=新节点();
int nodeId=Convert.ToInt32(((JValue)obj[“id”]).Value);
node.lat=Convert.ToDouble(((JValue)obj[“lat”]).Value);
node.lng=Convert.ToDouble(((JValue)obj[“lng”]).Value);
var listedessamefrom=fromNodeMap[nodeId];
foreach(ListedMessageFrom中的var边)
edge.fromNode=节点;
var listedgesasameto=toNodesMap[nodeId];
foreach(listedessameto中的变量边)
edge.toNode=节点;
添加(节点);
/*读到最后*/
graph.edges=graphEdges.ToArray();
graph.nodes=graphNodes.ToArray();
返回图;
}
免责声明我还没有测试过,但逻辑是存在的
现在我知道这里有foreach
循环,但不同的是,这里唯一的搜索是从词汇表中获取列表,我认为这是非常小的。我希望这对您有所帮助,或者至少给您另一种看待它的方式。您能先修改JSon和解析节点吗?这不可能通过简单的反序列化实现。使用反序列化获得图形对象后,您需要编写逻辑以通过IDI获取fromNode和toNode对象。是否有一个通过id获取对象的可选逻辑示例?通过节点id搜索节点集合,您就可以通过节点获取id—这听起来很简单