c#
Generic method to convert a flat JSON array to nested JSON
I have a JSON object as below [ { "Id": 7, "Name": "Colocation Folder", "ParentId": 1, "depth": 0 }, { "Id": 8, "Name": "CoLo Real Estate", "ParentId": 7, "depth": 1 }, { "Id": 10, "Name": "CoLo: Burst", "ParentId": 7, "depth": 1 }, { "Id": 34, "Name": "CoLo Dedicated Bandwidth", "ParentId": 7, "depth": 1 }, { "Id": 10035, "Name": "Infrastructure as a Service", "ParentId": 7, "depth": 1 }, { "Id": 10037, "Name": "Software as a Service", "ParentId": 7, "depth": 1 }, { "Id": 10038, "Name": "IaaS Component Upgrade", "ParentId": 7, "depth": 1 }, { "Id": 668, "Name": "CoLo Misc Folder", "ParentId": 7, "depth": 1 }, { "Id": 758, "Name": "CoLo: Conduit Fee", "ParentId": 668, "depth": 2 }, { "Id": 765, "Name": "CoLo: Private VLAN", "ParentId": 668, "depth": 2 } ] The Id and ParentId fields show the relation between the items. I need to make it as a nested JSON using C#. Since there will be many such models, I don't want to create individual classes for each model. Is there a generic approach in C# that will take a flat JSON array, take the ID and ParentId fields as input and then return me a nested JSON with all other fields in the array as well? For example, I am looking for an output of nested JSON as below: [ { "Id": 7, "Name": "Colocation Folder", "items": [ { "Id": 8, "Name": "CoLo Real Estate", "ParentId": 7 }, { "Id": 10, "Name": "CoLo: Burst", "ParentId": 7 }, { "Id": 34, "Name": "CoLo Dedicated Bandwidth", "ParentId": 7 }, { "Id": 10035, "Name": "Infrastructure as a Service", "ParentId": 7 }, { "Id": 10037, "Name": "Software as a Service", "ParentId": 7 }, { "Id": 10038, "Name": "IaaS Component Upgrade", "ParentId": 7 }, { "Id": 668, "Name": "CoLo Misc Folder", "ParentId": 7, "items": [ { "Id": 758, "Name": "CoLo: Conduit Fee", "ParentId": 668 }, { "Id": 765, "Name": "CoLo: Private VLAN", "ParentId": 668 } ] } ] } ]
If you use Json.Net, you can do this conversion in a generic way using the LINQ-to-JSON API (JObjects). The idea is to parse the JSON array and add all the individual items to a dictionary keyed by Id. Then, loop over the dictionary items, and for each one, try to look up the parent. If the parent is found, add the item to the parent's items array (creating it if needed). Otherwise, add the item to the root array. Along the way, remove the depth property from each item, since you don't seem to want that in the output. Lastly, just dump the root array to string to get the final result. var dict = JArray.Parse(json) .Children<JObject>() .ToDictionary(jo => (string)jo["Id"], jo => new JObject(jo)); var root = new JArray(); foreach (JObject obj in dict.Values) { JObject parent; string parentId = (string)obj["ParentId"]; if (parentId != null && dict.TryGetValue(parentId, out parent)) { JArray items = (JArray)parent["items"]; if (items == null) { items = new JArray(); parent.Add("items", items); } items.Add(obj); } else { root.Add(obj); } JProperty depth = obj.Property("depth"); if (depth != null) depth.Remove(); } Console.WriteLine(root.ToString()); Fiddle: https://dotnetfiddle.net/Buza6T
You can use a dynamic object with JSON.Net like so to detect your properties dynamically then you could build a new json object with the desired nesting: using Newtonsoft.Json; using Newtonsoft.Json.Linq; dynamic d = JArray.Parse(stringy); foreach(var ob in d) { if(ob.ParentID != ob.Id) { string debug = "oh snapple, it's a child object"; } }
Related Links
Adding a ReadOnly property to MaterialSingleLineTextField
WPF Update view in loop
How can i update blank TextBox to SQL in C#
LINQ expression duplicates values on select instead of cycling them
Using DI in ConfigureService-Methods (especially IApplicationLifetime) in .NET Core
C#: Map strings and binary data
is nested Linq faster than foreach loop? [closed]
Performance difference with various List intialization and population techniques
The name InitializeComponent does not exist in the current context (C#, WPF)
SQLite ExecuteNonQuery doesn't let me close the connection afterwards
log4net log file is not getting created in C#
Save image to web server from window application
Data not displaying in gmail attachment
How can I name a namespace dedicated to span just classes holding exclusively static fields? [closed]
.net core identity change tables names
Visual Studio - 'View Code' not working?