Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 用于包装JsonResult操作响应的.Net筛选器_C#_Asp.net_Asp.net Mvc_Asp.net Web Api_Action Filter - Fatal编程技术网

C# 用于包装JsonResult操作响应的.Net筛选器

C# 用于包装JsonResult操作响应的.Net筛选器,c#,asp.net,asp.net-mvc,asp.net-web-api,action-filter,C#,Asp.net,Asp.net Mvc,Asp.net Web Api,Action Filter,我已经构建了一个Web API应用程序,并发现了一个问题(目前在我的代码中处理得很糟糕),该问题总结在包装所有Json对象中,这些对象从所有API操作返回,并带有自定义节点(根) i、 e:我有一个json(数组)响应: [ { "Category": "Pages", "Users": [ { "ID": "1", "Fname": "Foo", "Lname": "Bar" } ] } ]

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

i、 e:我有一个json(数组)响应:

[
  {
    "Category": "Pages",
    "Users": [
      {
        "ID": "1",
        "Fname": "Foo",
        "Lname": "Bar"
      }
    ]
  }
]
{
  "Object": {
    "Body": [
      {
        "Category": "Pages",
        "Users": [
          {
            "ID": "1",
            "Fname": "Foo",
            "Lname": "Bar"
          }
        ]
      }
    ]
  }
}
需要这样的回应:

[
  {
    "Category": "Pages",
    "Users": [
      {
        "ID": "1",
        "Fname": "Foo",
        "Lname": "Bar"
      }
    ]
  }
]
{
  "Object": {
    "Body": [
      {
        "Category": "Pages",
        "Users": [
          {
            "ID": "1",
            "Fname": "Foo",
            "Lname": "Bar"
          }
        ]
      }
    ]
  }
}
因此,这里我只是将响应包装在
{“Object”:{“Body”:}}

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

对于简单的Json对象响应,我只需要像
{“object”:}

我用以下代码将Json响应当前包装在每个控制器操作中:

 public JsonResult Categories()
 {
   return Json(new { Object= new { Body= GetCategoriesList() } }, JsonRequestBehavior.AllowGet);
 }
当然这个成绩很糟糕,因为我必须在每个动作中重复这个包装

我的问题是:

如何创建
ActionFilterAttribute
,以便在每次操作执行后调用,从而按照上述Json示例包装响应

i、 e.用于创建过滤器:

 public class JsonWrapper: System.Web.Mvc.ActionFilterAttribute
 {
   public override void OnActionExecuted(ActionExecutedContext filterContext)
   {
   }
 }
[JsonWrapper]
public class APIController : Controller
i、 e.对于调用过滤器:

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

如果您要查找以下内容,还可以在同一筛选器中设置响应内容类型
“application/json”

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

为了避免在每个动作中重复包装,您可以编写一个扩展方法来完成包装

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类(并添加扩展方法以返回该类)


您可能需要一个自定义json序列化程序,而不是一个过滤器。谢谢,这很完美。如果我需要为json对象(而不是json对象数组)创建不同的包装,比如{“Body”:{“a”:1,“b”:2}并保留数组,该怎么办same@MoamenNaanou更改行
Data=new{Object=new{Body=jsonRes.Data}
到您喜欢的任何结构。@MoamenNaanou它是JsonArray,因为我们在这里的JsonResult上检查了它:
JsonResult jsonRes=context.Result作为JsonResult;if(jsonRes==null)return
我认为属性的使用会很混乱。如果不看代码,如果应用属性但返回ViewResult等会发生什么?如果坚持使用属性,则无需创建新的JsonResult并将其分配给上下文,只需执行
jsonRes.Data=new{Object=new{Body=jsonRes.Data}