规范化JSON以获得灵活的WebAPI响应

时间:2017-08-02 15:45:23

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

我有一个WebAPI方法,它根据请求在灵活的结构中返回Json。

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

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

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

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

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

Current 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; }
}

2 个答案:

答案 0 :(得分:0)

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

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

然后序列化字典变量就可以了。

答案 1 :(得分:-1)

如果您在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));