1

I have this structure in C# and I want to create JSON that can be translated to it successfully so that I can easily find my mistake in the JS logic.

public class Tree
{
        public Root Root { get; set; }
        public Tree()
        {}
}

public class Root : Node
{
        public Root(int _id, int _fk, string _name, string _code, List<Node> _children, List<Item> _leaves)
            : base(_id, _fk, _name, _code, _children, _leaves)
        {
        }

        public Root()
        { }
}

public abstract class Node
{
        public int? ID { get; set; }
        public int? FK { get; set; }
        public string Name { get; set; }
        public string Code { get; set; }
        public List<Node> children { get; set; }
        public List<Item> leaves { get; set; }

        public Node(int? _id, int? _fk, string _name, string _code, List<Node> _children, List<Item> _leaves)
        {
            ID = _id;
            FK = _fk;
            Name = _name;
            Code = _code;
            children = _children;
            leaves = _leaves;
        }
        public Node ()
        {}
}

public class Item
{
        public string Code { get; set; }
        public string Desc { get; set; }
        public string Uom { get; set; }
        public float? Measurements { get; set; }
        public int? FK { get; set; }
        public int? Tier { get; set; }
        public bool IsADPresent { get; set; }
}

and the basic most JSON I am trying to feed in command JsonConvert.DeserializeObject<Tree>(tree) is:

{
    "Tree": {
        "Root": {
            "children": [],
            "leaves": [],
            "FK": 1,
            "ID": 1,
            "Name": " LOGISTICS",
            "Code": "PT01"
        }
    }
}

but I still get null in Tree; let alone when the JSON gets much more hairy (the tree can have up to the 5th grandchild).

Thanks

UPDATE: upon removing Tree from JSON I am given exception: Newtonsoft.Json.JsonSerializationException: 'Could not create an instance of type StatusUpdater.Models.NPoco.Node. Type is an interface or abstract class and cannot be instantiated. Path 'Root.children[0].children', line 1, position 33.'

2 Answers2

3

You should remove Tree from your JSON as Tree is the destination type and don't need to be included in the JSON.

{
    "Root": {
        "children": [],
        "leaves": [],
        "FK": 1,
        "ID": 1,
        "Name": " LOGISTICS",
        "Code": "PT01"
    }
}

EDIT : In order to deserialize your abstract Node elements, you will need a concrete type and a custom converter. See Deserializing a collection of abstract classes and all duplicate links listed

An0d
  • 213
  • 2
  • 12
  • Your assurance of how it should be, helped me realize that I was actually dealing with 2 errors in the JSON and not 1. I had it like this before but got an exception JsonSerializationException due to mismatch in the mapping further down! I thought it was because of the missing Tree, added it and the exception did not occur. In reality, I caused another issue that masked the previous issue. All I had to do was remove an extra children node between Root and children[] (which in the example I put here I noticed). – Justin Farrugia Oct 21 '19 at 12:22
  • OK, it seems that this is only part of the answer. Removing Tree gets me back that Exception which actually makes sense. Since Node is abstract it's not managing to instantiate it of course. Any workaround pls? – Justin Farrugia Oct 21 '19 at 12:45
  • You could remove the keyword `abstract` on the `Node` class ? Or is it mandatory ? – An0d Oct 21 '19 at 13:09
  • Well, you will need a concrete type and a custom converter. See https://stackoverflow.com/questions/52808857/deserializing-a-collection-of-abstract-classes and all duplicate links listed – An0d Oct 21 '19 at 13:27
  • Yes I am already following an example myself. Thanks a real lot An0d. Kindly put this as an answer so that I mark it as the accepted. – Justin Farrugia Oct 21 '19 at 13:40
  • You're welcome. I updated my answer to include my comment about deserializing your abstract `Node` elements – An0d Oct 21 '19 at 13:43
1

For this json you will need to create a wrapper class.

public class X { public Tree {get; set;} } 

(...)

var tree = JsonConvert.DeserializeObject<X>(tree)?.Tree;


Why?

Let's examine the json.

{
    "Tree": {
        "Root": {
            "children": [],
            "leaves": [],
            "FK": 1,
            "ID": 1,
            "Name": " LOGISTICS",
            "Code": "PT01"
        }
    }
}

This json contains

        1 object with a property "Tree"

                which in turn has one property "Root"

                         which contains multiple properties

tymtam
  • 31,798
  • 8
  • 86
  • 126
  • you are correct but my question was how to edit the JSON and not the C# model. In fact I did the same thing from the JSON's side since I thought I had to pass in the Tree too due to misguided exceptions I received. – Justin Farrugia Oct 21 '19 at 12:17