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

Entity framework terms used with asp net mvc app
How to get the portion of image inside rectangle for cropping , windows phone 8
Use a binding to set the text property of a textbox in a usercontrol - WPF
C# Debug - cannot start debugging because the debug target is missing
Generic method in C#
tcp having trouble connecting c#
Are there commonly used delegates available in the standard class libraries?
How to set website theme to all webpages using a drop down list?
How to set selectedcolor of ColorCanvas by using Argb in code behind
How to set a transition property using Transitionals library
How to limit textbox maxlength by byte in winrt?
Entity Framework 6 database migrations for isolated multi-tenant setup
File upload / did I make a mistake choosing vb.net instead of php?
Find data in database
Calling sharepoint from web service
Baidu web search engine API

Categories

HOME
grizzly
compression
cxf
apache-storm
bigtable
crash
overrides
snmp
msbi
mediarecorder
uml-designer
genexus
rename
mongodb-replica-set
saucelabs
lambda-calculus
popup
reportlab
powerpivot
draw2d
computation-theory
custom-component
android-wifi
tcpdf
wai-aria
advertising
pixels
rancher
expressionengine
mex
request-uri
r-factor
openoffice-impress
andengine
overflow
spring-oauth2
offset
mootools
intersection
dom4j
campaign-monitor
scip
anypoint-studio
mapquest
jslider
python-venv
codepen
risc
synchronized
automapper-4
remap
rmq
sharing
blackberry-webworks
distcc
boost-range
jira-agile
patching
usps
bbedit
firefox-os
bluetooth-lowenergy-4.2
jquery-draggable
jain-sip
vanilla-forums
consul-template
bungeecord
drools-guvnor
yosemite
dirname
oxygenxml
drawable
debuggervisualizer
smartxls
image-preloader
xcode6.1-gm-seed
xcode5.1
google-oauth-java-client
scidb
aspnet-compiler
proj4
latex-suite
msbuild-task
servicemanager
gmail-imap
system.transactions
jqzoom
vectorwise
windows-xp-embedded
cryptolicensing
hs-err
moores-law

Resources

Mobile Apps Dev
Database Users
javascript
java
csharp
php
android
MS Developer
developer works
python
ios
c
html
jquery
RDBMS discuss
Cloud Virtualization
Database Dev&Adm
javascript
java
csharp
php
python
android
jquery
ruby
ios
html
Mobile App
Mobile App
Mobile App