0

I have a DataTable which contains a tree structure. I want to convert that into JSON object which I can bind to a ExtJS tree. I am able to convert the DataTable into tree structure (Thank to one of Stackoverflow user) but not able to convert it into JSON. I want to return JSON object which I should be able to bind to EXTJs tree.

**I don't want to do this: string json = JsonConvert.SerializeObject(table, Formatting.Indented);

This will just convert the DataTable into JSON but it will not keep the parent child relationship.**

Here is my code.

 public class Node<T>
    {
        public T Item { get; internal set; }
        public int Level { get; internal set; }
        public Node<T> Parent { get; internal set; }
        public IList<Node<T>> Children { get; internal set; }

    }


 public static class Program
    {
        private static void Main(string[] args)
        {
            DataTable table = new DataTable();
            table.Columns.Add("name", typeof(string));
            table.Columns.Add("key", typeof (string));
            table.Columns.Add("parentkey", typeof (string));
            table.Columns.Add("Level", typeof (int));


            table.Rows.Add("A", "A1", null, 1);
            table.Rows.Add("B", "A2", "A1", 2);
            table.Rows.Add("C", "A3", "A1", 2);
            table.Rows.Add("D", "A4", "A1", 2);

            table.Rows.Add("E", "A5", "A2", 3);
            table.Rows.Add("F", "A6", "A5", 4);
            table.Rows.Add("G", "A7", "A3", 3);
            table.Rows.Add("H", "A8", "A4", 3);


            table.Rows.Add("I", "A9", "A4", 3);
            table.Rows.Add("J", "A10", "A4", 3);
            table.Rows.Add("K", "A11", "A10", 4);
            table.Rows.Add("L", "A12", "A10", 4);

            table.Rows.Add("M", "A13", "A12", 5);
            table.Rows.Add("N", "A14", "A12", 5);
            table.Rows.Add("O", "A15", "A10", 4);

            table.Rows.Add("P", "A16", null, 1);
            table.Rows.Add("Q", "A17", "A16", 2);

            DataView view = table.DefaultView;

            // By default, the first column sorted ascending.
            view.Sort = "Level, ParentKey DESC";


            var hierarchy =
                table.AsEnumerable()
                    .ToHierarchy(row => row.IsNull("parentkey"),
                                 (parent, child) => parent.Field<string>("key") ==
                                                    child.Field<string>("parentkey"));


           //HOW TO CONVERT THIS HIERARCHY INTO JSON???

            Console.ReadKey();

        }

        public static IEnumerable<Node<T>> ToHierarchy<T>(this IEnumerable<T> source,Func<T, bool> startWith, Func<T, T, bool> connectBy)
        {
            if (source == null) throw new ArgumentNullException("source");
            if (startWith == null) throw new ArgumentNullException("startWith");
            if (connectBy == null) throw new ArgumentNullException("connectBy");
            return source.ToHierarchy(startWith, connectBy, null);
        }

        private static IEnumerable<Node<T>> ToHierarchy<T>(this IEnumerable<T> source,Func<T, bool> startWith,Func<T, T, bool> connectBy,Node<T> parent)
        {
            int level = (parent == null ? 0 : parent.Level + 1);

            var roots = from item in source
                        where startWith(item)
                        select item;
            foreach (T value in roots)
            {
                var children = new List<Node<T>>();
                var newNode = new Node<T>
                {
                    Level = level,
                    Parent = parent,
                    Item = value,
                    Children = children.AsReadOnly()
                };

                T tmpValue = value;
                children.AddRange(source.ToHierarchy(possibleSub => connectBy(tmpValue, possibleSub), connectBy, newNode));

                yield return newNode;
            }
        }
    }
SharpCoder
  • 18,279
  • 43
  • 153
  • 249
  • possible duplicate of [C# DataTable to Json?](http://stackoverflow.com/questions/13326777/c-sharp-datatable-to-json) – Bob. Aug 19 '13 at 12:02
  • @Bob. I want to maintain parent child relationship while converting object into JSON. using string json = JsonConvert.SerializeObject(table, Formatting.Indented); would just convert every row into JSON without taking into consideration the parent child relationship. – SharpCoder Aug 19 '13 at 12:08
  • what is wrong with `JsonConvert.SerializeObject(hierarchy);` ? – I4V Aug 19 '13 at 12:10
  • Have you tried it on your `var hierarchy` object? – Bob. Aug 19 '13 at 12:12
  • @Bob. Well, the hierarchy object is having parent child relation but not really sure how to convert it. I am still working with that object & hoping I will be able to convert it. – SharpCoder Aug 19 '13 at 12:30
  • @I4V: JsonConvert.SerializeObject(hierarchy); just converts the object into JSON . It does not maintains parent child relation. I want to pass the JSON to EXtJS tree which needs data in parent child format – SharpCoder Aug 19 '13 at 12:32
  • @Brown_Dynamite No, it **does** maintain the hierarchy. Converting *something* to json means also to keep all parent-child relations. – I4V Aug 19 '13 at 12:39
  • @I4V: Thank you for reply. in the code I have shared, if before console.readKey(), if you add "string json = JsonConvert.SerializeObject(table, Formatting.Indented);" it will simple generate following output. [ { "name": "A", "key": "A1", "parentkey": null, "Level": 1 }, { "name": "B", "key": "A2", "parentkey": "A1", "Level": 2 }, { "name": "C", "key": "A3", "parentkey": "A1", "Level": 2 }, { "name": "D", "key": "A4", "parentkey": "A1", "Level": 2 }, .... Which is just flat JSON :( – SharpCoder Aug 19 '13 at 12:52
  • @Brown_Dynamite which means `hierarchy` is flat. It seems you have a bug in `ToHierarchy` method. Not Json.Net's fault. – I4V Aug 19 '13 at 12:56
  • @I4V: I never meant that its fault from JSON.NET library when I use JsonConvert.SerializeObject(hierarchy); I get "{"Self referencing loop detected for property 'Parent' with type 'SortDataTable.Node`1[System.Data.DataRow]'. Path '[0].Children[0]'."}" error. I am not sure that the extension method I am using is correct or not. I am looking at the best way to convert datatable in JSON with parent child relation. There is a good chance my approach is wrong. – SharpCoder Aug 19 '13 at 13:03
  • possible duplicate of [Serialize one to many relationships in Json.net](http://stackoverflow.com/questions/5769200/serialize-one-to-many-relationships-in-json-net) – Ed Chapel Aug 24 '13 at 19:57

0 Answers0