I have to convert a TreeView
object to JSON using C#. I am currently using JsonConvert.SerializeObject()
.
public class SubTreeNode : TreeNode
{
public CustomProperties customProperties;
}
public class CustomProperties
{
public string property1 = "Property1";
public string property2 = "Property2";
public string property3 = "Property3";
}
When tried it with JsonConvert.SerializeObject(treeView1.Nodes);
it only returned the top nodes... not the child nodes, sub-child, and so on.
What is the easiest way to serialize and deserialize this TreeView object?
You will need to add methods that produce JSON from each node recursively.
Check out the related post: Serializing a Tree into Json Object.
I was confronted with the same problem: only top nodes are exported with the standard JSON.Net Serializer because, as fero under the above link rightly states, "your TreeNode class is serialized as an array because it implements IEnumerable". It further says you should decorate the TreeNode class with the JsonConverterAttribute. I didn't get this to work.
Here is an alternative. Please note that this may not be seen as the best way to do it. But it is pretty simple:
- you are using standard TreeNode class and your data is stored in a TreeView
- you want to use JSON.NET Serializer
Create a new hierarchical class with the information you want to export in JSON (in my case, I only want to export part of my treenode-properties, so creating a new simple class made sense twice):
'Simplified version of tree for json
'Compared to TreeNode class, this object is also serializable with the standard JSON.NET Serializer
Public Class JTree
Public children As New List(Of JTree)()
Private _name As String
Public Property name() As String
Get
Return _name
End Get
Set(value As String)
_name = value
End Set
End Property
Private _id As String
Public Property id() As String
Get
Return _id
End Get
Set(value As String)
_id = value
End Set
End Property
End Class
Recursively move your data from TreeView to a new JTree (our custom class):
Public Sub createSimplifiedJSONTree(parentNode As TreeNode, ByRef JTreeSimp As JTree)
'Start recursion on all subnodes
For Each childNode As TreeNode In parentNode.Nodes
Dim jchild As New JTree
jchild.id = childNode.Name
jchild.name = childNode.Text
JTreeSimp.children.Add(jchild)
createSimplifiedJSONTree(childNode, jchild)
Next
End Sub
Write simplified JSON tree to file using JSON.NET Serializer:
Private Sub WriteJSONfromTreeview()
Dim rootNode As TreeNode = TreeView1.Nodes(0)
Dim JTreeSimp As New JTree
createSimplifiedJSONTree(rootNode, JTreeSimp)
'serialize JSON directly to a file using JSON.Net Serializer
Using file__1 As StreamWriter = File.CreateText("c:\temp\test.txt")
Dim serializer As New JsonSerializer()
serializer.Formatting = Formatting.Indented
serializer.Serialize(file__1, JTreeSimp)
End Using
End Sub
Final txt (example):
{
"children": [
{
"children": [
{
"children": [
{
"children": [
{
"children": [
{
"children": [
{
"children": [
{
"children": [],
"name": "alcatraz",
"id": "021_3",
"size": 166
}
],
"name": "skyline",
"id": "031_3",
"size": 167
}
],
"name": "city",
"id": "041_5",
"size": 167
}
],
"name": "coit",
"id": "051_4",
"size": 169
}
],
"name": "tower",
"id": "061_3",
"size": 170
}
],
"name": "telegraphhill",
"id": "071_3",
"size": 170
}
],
"name": "coittower",
"id": "081_2",
"size": 170
},
{
"children": [
{
"children": [],
"name": "sunset",
"id": "071_112",
"size": 3
}
],
"name": "berkeley",
"id": "081_109",
"size": 3
},
{
"children": [
{
"children": [],
"name": "marin",
"id": "071_77",
"size": 3
}
],
"name": "marinheadlands",
"id": "081_110",
"size": 3
}
],
"name": "root",
"id": "000",
"size": 0
}
using custom json serializer worked for me
var settings = new JsonSerializerSettings
{
Converters = new List<JsonConverter> { new OrgChartConverter() },
Formatting = Formatting.Indented
};
string json = JsonConvert.SerializeObject(tree, settings);
public class OrgChartConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(Node<T>).IsAssignableFrom(objectType);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
Node<T> node = (Node<T>)value;
JObject obj = new JObject();
obj.Add("Name", node.Value.Name);
obj.Add("Children", JArray.FromObject(node.Children, serializer));
obj.WriteTo(writer);
}
public override bool CanRead
{
get { return false; }
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}