Reputation: 135
I have a nested dictionary object output like below
{
"name":"test",
"id":1,
"parent": {
"name":"test1",
"id":2,
"parent":{
"name":"test2",
"id":3,
"parent":{
"name":"test3",
"id":4,
"parent":{
....
}
}
}
}
}
Here is the code that returns dictionary object:
class GetData
{
public HttpWebResponse WebResponse { get; private set; }
public Dictionary<string, object> Data { get; private set; }
public GetData(HttpWebResponse webResponse, Dictionary<string, object> data)
{
WebResponse = webResponse;
Data = data;
}
}
I have a object that holds the above response like below:
var responseData = GetResponseData(req);
Now I want to convert the above dictionary object to c# object. The following is my c# object
class SomeClass
{
public int Id { get; }
public string Name { get; }
public SomeClass Parent { get; }
public IEnumerable<SomeClass> GetAncestry()
{
if (Parent is not null)
{
yield return Parent;
foreach (var ancestor in Parent.GetAncestry()) yield return ancestor;
}
}
}
I am trying the below way to convert my dictionary object to 'SomeClass' object, but it is not working for me. Can someone help me out with it?
List<SomeClass> smClass = new List<SomeClass>(responseData .Values);
Upvotes: 0
Views: 1017
Reputation: 318
Try create struct (or class) eg.:
public class NamedObject
{
int id {get; set;}
string name {get; set;}
NamedObject parent {get; set;}
}
Then you can deserialize your json by Newtonsoft.Json.JsonConvert.DeserializeObject (you need Newtonsoft.Json library or NuGet package)
NamedObject namedObject = JsonConvert.DeserializeObject<NamedObject>(json);
Working example (from your previous question):
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
namespace ConsoleApp1
{
internal class Program
{
private static void Main(string[] args)
{
Console.WriteLine("Hello World!");
string s = "{ \"name\":\"test\", \"id\":1, \"parent\": { \"name\":\"test1\", \"id\":2, \"parent\":{ \"name\":\"test2\", \"id\":3, \"parent\":{ \"name\":\"test3\", \"id\":4, \"parent\": null } } } }";
TreeNode node = JsonConvert.DeserializeObject<TreeNode>(s);
}
}
public class TreeNode
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("id")]
public int ID { get; set; }
public NodeType Type { get; }
public Dictionary<TreeNode, NodeType> Childern { get; }
public TreeNode GetChildernByName(string name) => Childern.First(x => x.Key.Name == name).Key;
[JsonProperty("parent")]
public TreeNode Parent { get; private set; }
public string FullName => IsRoot ? string.Empty : this.Parent.FullName + "/" + Name;
public TreeNode(string name, NodeType type, TreeNode parent)
{
this.Name = name;
this.Type = type;
this.Parent = parent;
this.Childern = new Dictionary<TreeNode, NodeType>();
}
public TreeNode()
{
}
public TreeNode(string name) : this(name, NodeType.Folder, null) { }
public TreeNode(string name, NodeType type) : this(name, type, null) { }
public bool IsRoot => Parent == null;
public void AddChild(params TreeNode[] nodes) => AddChild(true, nodes);
public void AddChild(bool setParent, params TreeNode[] nodes)
{
foreach (TreeNode node in nodes)
{
Childern.Add(node, node.Type);
if (setParent) node.Parent = this;
}
}
public IEnumerable<TreeNode> GetFullPath()
{
List<TreeNode> parents = new List<TreeNode>();
if (this.Parent != null)
{
parents.AddRange(Parent.GetFullPath());
}
parents.Add(this);
return parents;
}
public override string ToString() => Name;
}
public enum NodeType
{
Folder,
File
}
}
You can use same name for public fields as they are in json, or you can set JsonProperty Attribute where you need. Only remember, you must have constructor without parameters and I reccomand use nullable types (eg. int?)
Upvotes: 2