修改JSON输出

时间:2014-05-28 21:26:49

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

我有一个返回List<AttributeCollection>的Web API方法。 AttributeCollection显然是一个属性列表,其中包含每个属性的值(在本例中由CRM 2011 SDK提取)。

以下是该方法返回的JSON:

[
    [
        {
            "Key": "mobilephone",
            "Value": "(430) 565-1212"
        },
        {
            "Key": "firstname",
            "Value": "John"
        }
    ],
    [
        {
            "Key": "mobilephone",
            "Value": "(430) 565-1313"
        },
        {
            "Key": "firstname",
            "Value": "Mark"
        }
    ]
]

现在,第一对括号是List的直观表示,然后每个[]都有多对括号(AttributeCollection)。

我想摆脱第一对括号,将其替换为顶级元素名称(即:allAttributes),然后替换所有后续项目。

我过度使用了WriteToStreamAsync

JsonMediaTypeFormatter方法
public override System.Threading.Tasks.Task WriteToStreamAsync(Type type, object value, System.IO.Stream writeStream, HttpContent content, TransportContext transportContext)
{
    if ((typeof(IEnumerable<AttributeCollection>).IsAssignableFrom(type)))
    {
        //anything I could do here ?
    }


    return base.WriteToStreamAsync(type, value, writeStream, content, transportContext);
        } 

我想过操纵JSON字符串本身,但它似乎无法从那里访问。

有什么想法吗?

感谢。

1 个答案:

答案 0 :(得分:1)

如果您想在格式化程序本身上执行此操作,您可能需要将包装代码写入writeStream,如下面的代码(在记事本中测试):

public override async Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
{
    if ((typeof(IEnumerable<AttributeCollection>).IsAssignableFrom(type)))
    {
        var list = (IEnumerable<AttributeCollection>)value;
        byte[] headerBytes = Encoding.UTF8.GetBytes("{\"allAttributes\":");
        byte[] footerBytes = Encoding.UTF8.GetBytes("}");
        writeStream.Write(headerBytes, 0, headerBytes.Length);
        foreach (var item in list)
        {
            await base.WriteToStreamAsync(item.GetType(), item, writeStream, content, transportContext);
        }

        writeStream.Write(footerBytes, 0, footerBytes.Length);
    }
    else
    {
        return await base.WriteToStreamAsync(type, value, writeStream, content, transportContext);
    }
}

另一种方法是创建一个包装类并将其序列化:

public class MyWrappingClass
{
    public IEnumerable<AttributeCollection> allAttributes { get; set; }
}

public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
{
    if ((typeof(IEnumerable<AttributeCollection>).IsAssignableFrom(type)))
    {
        var list = (IEnumerable<AttributeCollection>)value;
        var obj = new MyWrappingClass { allAttributes = list };
        return base.WriteToStreamAsync(obj.GetType(), obj, writeStream, content, transportContext);
    }
    else
    {
        return base.WriteToStreamAsync(type, value, writeStream, content, transportContext);
    }
}