Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 按id使用子对象反序列化JSON_C#_Json_Xamarin_Json.net_Deserialization - Fatal编程技术网

C# 按id使用子对象反序列化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

我有以下JSON:

 {
    "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—这听起来很简单