将"标准"JSON字段添加到REST API中的序列化对象

tnt*_*off 1 rest json json.net asp.net-web-api

由此推动:Google JSON样式指南,我想在我的rest API中插入一些自定义序列化逻辑.我正在使用WebAPI 2和JSON.NET.我的目标是将我的响应的"有效负载"包装在主JSON响应的"数据"字段中,如样式指南中所述,在每个响应中包含一个apiVersion字段,以及类似的东西.当然控制器动作只是直接返回POCO,我想修改它们发送到的容器,而不是POCO本身,所以:

{
  "id": "111",
  "apiVersion": "1.0",
  "data": {
    "kind": "monkey",
    "name": "manny",
    "age": "3"
  },
  "error": null
}
Run Code Online (Sandbox Code Playgroud)

......那种事.所以我设想在它通过线路之前将少量标准数据插入到每个响应中.实现这一目标的最佳方法是什么?

TIA.

Sim*_*ger 5

我相信你可以用a ActionFilterAttribute来实现这种行为.您首先需要创建一个类来表示包装的响应(所有属性都是字符串,根据需要调整):

public class WrappedJsonResponse
{
    public string Id {get;set;}
    public string ApiVersion {get;set;}
    public object Data {get;set;}
    public string Error {get;set;}
}
Run Code Online (Sandbox Code Playgroud)

ActionFilterAttribute允许您通过虚拟动作的执行后做一些处理OnActionExecuted方法:

public class WrappedJsonAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(HttpActionExecutedContext context)
    {
        // A POCO response will normally be wrapped in an ObjectContent
        var content = context.Response.Content as ObjectContent

        if(content != null)
        {
            // Create the WrappedJsonResponse object appropriately and
            // put the original result in the Data property
            content.Value = new WrappedJsonResponse { Data = content.Value };
            content.ObjectType = typeof(WrappedJsonResponse);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

使用该属性,您可以选择将其应用到您想要的位置(整个控制器,仅限操作或默认过滤器).

注意:我目前无法访问开发环境,也没有测试过滤器.如果这还不完整,至少应该让你知道如何做到这一点.