.Net过滤器用于包装JsonResult操作响应

时间:2016-08-24 10:29:39

标签: c# asp.net asp.net-mvc asp.net-web-api action-filter

我已经构建了一个 Web API应用程序并发现了一个问题(目前在我的代码中处理不当),这个问题总结在包装从All返回的所有Json个对象中具有自定义节点(根)的API操作。

即:我有这个json(数组)响应:

[
  {
    "Category": "Pages",
    "Users": [
      {
        "ID": "1",
        "Fname": "Foo",
        "Lname": "Bar"
      }
    ]
  }
]

需要此回复:

{
  "Object": {
    "Body": [
      {
        "Category": "Pages",
        "Users": [
          {
            "ID": "1",
            "Fname": "Foo",
            "Lname": "Bar"
          }
        ]
      }
    ]
  }
}

所以我在这里将响应包装在{"Object":{"Body": <Response Here>}}

我需要将它应用于Array类型的所有API Json响应。

对于简单的Json对象响应,我需要它像{"Object": <Response Here>}

一样包裹

我通过以下代码将每个控制器操作中的Json响应包装起来:

 public JsonResult Categories()
 {
   return Json(new { Object= new { Body= GetCategoriesList() } }, JsonRequestBehavior.AllowGet);
 }

当然,这个成就是如此糟糕,因为我必须在每个动作中重复这个包装。

我的问题是:

如何在每个动作执行后创建ActionFilterAttribute以根据上述Json样本包装响应?

即。用于创建过滤器:

 public class JsonWrapper: System.Web.Mvc.ActionFilterAttribute
 {
   public override void OnActionExecuted(ActionExecutedContext filterContext)
   {
   }
 }

即。用于调用过滤器:

[JsonWrapper]
public class APIController : Controller

还可以在同一过滤器"application/json"

中设置响应内容类型

2 个答案:

答案 0 :(得分:3)

如果想在这里找你想要的东西:

public class JsonWrapperAttribute : ActionFilterAttribute, IActionFilter
{
    void IActionFilter.OnActionExecuted(ActionExecutedContext context)
    {
        //Check it's JsonResult that we're dealing with
        JsonResult jsonRes = context.Result as JsonResult;
        if (jsonRes == null)
            return;

        jsonRes.Data = new { Object = new { Body = jsonRes.Data } }
    }
}

以下是如何使用它:

[JsonWrapper]
public JsonResult Index()
{
    var data = new
    {
        a = 1,
        b = 2
    };
    return Json(data, JsonRequestBehavior.AllowGet);
}

结果将是:

{"Object":{"Body":{"a":1,"b":2}}}

答案 1 :(得分:2)

为了防止自己不得不在每个动作中重复包装,你可以编写一个扩展方法来为你做包装

public static class ControllerExtensions 
{
    public static JsonResult WrappedJson(this Controller controller, object data, JsonRequestBehavior behavior)
    {
        return new JsonResult
        {
            Data = new { Object = new { Body = data } },
            JsonRequestBehavior = behavior
        };
    }
}

或创建一个新的ActionResult类(并添加扩展方法以返回该类)

public class WrappedJsonResult : JsonResult
{
    public new object Data
    {
        get
        {
            if (base.Data == null)
            {
                return null;
            }

            return (object) ((dynamic) base.Data).Object.Body;
        }

        set { base.Data = new {Object = new {Body = value}}; }
    }
}