繁体   English   中英

如何在C#中创建嵌套的(parent-Child)JSON响应?

[英]How to create a nested (parent-Child ) JSON response in c#?

我正在制作一个Web服务,它将以JSON格式给出响应。 我已经从SQL Server提取了数据并将其存储在Datatable中。 dt的外观如下:-

id      Caption                 pid
F182    GLOBAL REPORTS          NULL
F184    software                NULL
F1227   LYB P&L Reports         F184
F1245   LYB Training            F184
F1239   test3                   F182
F1249   Paavan_Test_Reports     F184

标题列中pid为Null的项是父项,并且它们的子项与各自父级id的 pid相同。

例如: GLOBAL REPORTS有1个孩子,即test3软件有3个孩子。

我希望将JSON响应转换为以下格式

[{ 
    id='F182',  
    caption='GLOBAL REPORTS',
    pid=null;
    items:[{
    id='F1239',
    caption='test3',
    pid='F182'}] 
    },
    { 
    id='F184',
    caption='software',
    pid='NULL',
    items:[{
    id='F1227',
    caption='LYB P&L Reports',
    pid='F184'
    },
    {
    id='F1245',
    caption='LYB Training',
    pid='F184'
    },
    { 
    id='F1249',
    caption='Paavan_Test_Reports',
    pid='F184'
    }
}]

我做了一个班级文件夹

    class folder
    {
    string id{get;set;}
    string pid{get;set;}
    string caption{get;set;}
   }

我如何获取将包含特定父级的所有可用子级的对象数组? 我是Json对象和响应的新手,

我尝试使用以下方法:

 var obj = dt.AsEnumerable()
                .GroupBy(r => r["pid"])
                .ToDictionary(g => g.Key.ToString(),
                              g => g.Select(r => new {
                              item = r["caption"].ToString(),
                              }).ToArray());
     var json = JsonConvert.SerializeObject(obj);

但这给了我一个没有任何层次的简单json响应。

您需要在序列化之前构建对象层次结构。 为此,请在folder类中定义一个新属性:

public IEnumerable<folder> items { get; set; }

现在,您可以递归地搜索每个根folder

public static IEnumerable<folder> BuildTree(folder current, folder[] allItems)
{
    var childs = allItems.Where(c => c.pid == current.id).ToArray();
    foreach (var child in childs)
        child.items = BuildTree(child, allItems);
    current.items = childs;
    return childs;
}

用法:

var input = new[] // dt.AsEnumerable() in your case
{
    new folder {id = "F182",  caption = "GLOBAL REPORTS",      pid = null   },
    new folder {id = "F184",  caption = "software",            pid = null   },
    new folder {id = "F1227", caption = "LYB P&L Reports",     pid = "F184" },
    new folder {id = "F1245", caption = "LYB Training",        pid = "F184" },
    new folder {id = "F1239", caption = "test3",               pid = "F182" },
    new folder {id = "F1249", caption = "Paavan_Test_Reports", pid = "F184" },
};

var roots = input.Where(i => i.pid == null);
foreach (var root in roots)
    BuildTree(root, input);

var json = JsonConvert.SerializeObject(roots, Formatting.Indented);

另外,如果要隐藏空items ,则可以在folder类中定义方法ShouldSerialize

public bool ShouldSerializeitems()
{
    return items.Any();
}

演示在这里

我认为您想要的是在文件夹中包含一个文件夹列表,如下所示:

class folder
{
    string id{get;set;}
    string pid{get;set;}
    string caption{get;set;}
    List<folder> items {get;set;}
}

在这种情况下使用JSONConvert时,如果在子级集合中存在父级,则可能会遇到循环依赖项。 您可以使用SerializerSettings对象忽略这些情况,对于项列表中的子项,可以将其集合设置为null,这样就不会序列化。

但是,您指定的所需输出还会列出文件夹数组。 因此,最后,您需要序列化文件夹类的集合(例如,列表或数组)。 就像是。

关于如何加载数据,我想您已经加载了具有id,pid和caption的文件夹,但是items属性为空。

为了建立父母/子女关系,您可以这样

var folders = dt.AsEnumerable().ToList();

foreach(var folder in folders) {
    folder.items = folders.Where(f => f.pid.Equals(folder.id)).ToList();
}

var parentFolders = folders.Where(f => f.pid is null);

var json = JsonConvert.SerializeObject(parentFolders, new SerializerSettings () {
    ReferenceLoopHandling = ReferenceLoopHandling.Ignore
    });

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM