c# - 如何在 C# 中创建嵌套(父子)JSON 响应?

我正在制作一个 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 的项目是 parent ,他们有与各自 parent 的 id 具有相同 pid 的 child .

例如: GLOBAL REPORTS 有 1 个 child ,即 test3 并且 software 有 3 个 child 。

我希望 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;}
   }

如何获取对象数组items,其中包含特定父项的所有可用子项?我是 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; }

现在您可以递归搜索每个根文件夹的子级:

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();
}

演示是 here

https://stackoverflow.com/questions/52862601/

相关文章:

apache - 使用 ApacheDS 创建新的架构 LDAP

r - ggplot2 以错误的顺序放置数据标签(geom_text)

react-native - 如何在不影响内部 View 元素的情况下应用阴影来 react 原生

perl - Docker [for mac] 文件系统变为只读,这几乎破坏了 docker 的所有

jsf-2 - ResponseWriter.writeAttribute() 中 'name' 和

assembly - ARM v8 中的 LDUR 和 STUR

vuejs2 - 如何在 v-radio 标签中设置 HTML

authentication - Kubernetes 基于 LDAP 的用户身份验证

sas - 对SAS中的动态列数进行排名

powershell - 在 Powershell 中实现装饰器模式