【问题标题】:Normalise JSON for flexible WebAPI response标准化 JSON 以实现灵活的 WebAPI 响应
【发布时间】:2017-08-03 19:30:01
【问题描述】:

我有一个 WebAPI 方法,它以取决于请求的灵活结构返回 Json。

部分问题在于可能有任意数量的列,并且它们可以是任何类型。下面给出的 2 个(代码和计数)只是一个示例。

此结构基于底层类,但输出中可以有任意数量的列。因此,与您可能期望的通常属性不同,这些是具有NameValue 属性的集合中的对象。

这种灵活方法的缺点是它提供了一种非标准格式。

有没有办法将其转换为更标准化的形状?是否有一些属性可以添加到类属性中以更改它们的序列化方式?

例如,有 2 列 - Code(字符串)和 Count(数字):

当前 Json:

{
    "Rows": [
        {
            "Columns": [
                {
                    "Value": "1",
                    "Name": "Code"
                },
                {
                    "Value": 13,
                    "Name": "Count"
                }
            ]
        },
        {
            "Columns": [
                {
                    "Value": "2",
                    "Name": "Code"
                },
                {
                    "Value": 12,
                    "Name": "Count"
                }
            ]
        },
        {
            "Columns": [
                {
                    "Value": "9",
                    "Name": "Code"
                },
                {
                    "Value": 1,
                    "Name": "Count"
                }
            ]
        },
        {
            "Columns": [
                {
                    "Value": "5",
                    "Name": "Code"
                },
                {
                    "Value": 2,
                    "Name": "Count"
                }
            ]
        }
    ]
}

理想情况下我想把它改成这样:

{
    "Rows": [
        {
            "Code": "1",
            "Count": 13
        },
        {
            "Code": "2",
            "Count": 12
        },
        {
            "Code": "9",
            "Count": 1
        },
        {
            "Code": "5",
            "Count": 2
        }
    ]
}

控制器方法(C#)

    public ReportResponse Get(ReportRequest request)
    {
        var result = ReportLogic.GetReport(request);
        return result;
    }

输出类

public class ReportResponse
{
    public List<ReportRow> Rows { get; set; }
    public ReportResponse()
    {
        Rows = new List<ReportRow>();
    }
}
public class ReportRow
{
    public List<ReportColumn> Columns { get; set; }
    public ReportRow()
    {
        Columns = new List<ReportColumn>();
    }
}
public class ReportColumn<T> : ReportColumn
{
    public T Value { get; set; }
    public ReportColumn(string name)
    {
        Name = name;
    }
}
public abstract class ReportColumn
{
    public string Name { get; internal set; }
}

【问题讨论】:

  • 发现LINQ to JSON来自天堂的法力。这应该会让你继续前进
  • Oo 从来没有听说过 - 现在查找它:D
  • 你返回的结构是什么?在返回之前你可以在它上面做一些 linqy 的事情
  • 只是痛苦,您想要的输出实际上是无效的 json。我假设你只想要数组输出?
  • @Padraic 是的,这是正确的:p

标签: c# json asp.net-web-api


【解决方案1】:

我认为最简单的方法是在序列化之前将您的类映射到字典。比如:

var dictionaries = List<Dictionary<string, object>();
foreach(var column in rows.Columns)
{
    dictionaries.Add(new Dictionary<string, object>{{column.Name, column.Value}});
}

然后序列化字典变量应该可以解决问题。

【讨论】:

  • 我相信 LINQ-y 的人会有更简洁的方法来做到这一点!
  • 虽然不是所有的列值都是字符串。有没有办法保留类型?
  • @CompanyDroneFromSector7G 而不是 Dictionary 您可以使用 Dictionary 它将接受值 wolf 任何类型并在序列化时保留该类型。
  • 其实这也没用,我还是得到了原来的结构。
  • 您是否从 Web api 控制器操作中返回新字典?
【解决方案2】:

如果你在 JavaScript 中使用输出,你可以翻译如下:

    var
        data = {
            "Rows": [
                {
                    "Columns": [
                        {
                            "Value": "1",
                            "Name": "Code"
                        },
                        {
                            "Value": 13,
                            "Name": "Count"
                        }
                    ]
                },
                {
                    "Columns": [
                        {
                            "Value": "2",
                            "Name": "Code"
                        },
                        {
                            "Value": 12,
                            "Name": "Count"
                        }
                    ]
                },
                {
                    "Columns": [
                        {
                            "Value": "9",
                            "Name": "Code"
                        },
                        {
                            "Value": 1,
                            "Name": "Count"
                        }
                    ]
                },
                {
                    "Columns": [
                        {
                            "Value": "5",
                            "Name": "Code"
                        },
                        {
                            "Value": 2,
                            "Name": "Count"
                        }
                    ]
                }
            ]
        },
        output = [
        ];

    data.Rows.forEach(function (row)
    {
        var
            newRow = {};

        row.Columns.forEach(function (column)
        {
            newRow[column.Name] = column.Value;
        });

        output.push(newRow);
    })

    console.log(JSON.stringify(output));

【讨论】:

  • bambam 你听说过地图功能吗??
  • 对不起,我想在返回之前用 C# 转换 Json。
  • @dobleUber - 不,告诉我更多。
  • @CompanyDroneFromSector7G - 没问题!这是一个不知道您的数据集有多大或如何使用的建议。
猜你喜欢
  • 2018-02-24
  • 2022-01-16
  • 1970-01-01
  • 2019-04-27
  • 1970-01-01
  • 2015-07-11
  • 1970-01-01
  • 2011-08-27
  • 2020-01-09
相关资源
最近更新 更多