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

标签 c# json visual-studio linq

我正在制作一个 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

关于c# - 如何在 C# 中创建嵌套(父子)JSON 响应?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52862601/

相关文章:

c# - 在 Word 中按字体选择文本

php - 在 PHP 中通过 JSONArray 进行 Foreach

c# - SMTP 错误的命令序列。服务器响应是 : You must authenticate first (#5. 5.1)

java - 从 JSON 文件解析时无法从 JsonElement 转换为 String

java - RestFul 服务(spring3)客户端 java?

visual-studio - 如何在 Visual Studio 中打开右侧的新文档选项卡标签?

visual-studio - Visual Studio 颜色未正确加载

c++ - 为什么汉字经过编译器会变成乱码?

c# - 按顺序合并两个或多个列表

c# - 创建和使用 c# 应用程序文件夹