C# 用于包装JsonResult操作响应的.Net筛选器
我已经构建了一个Web API应用程序,并发现了一个问题(目前在我的代码中处理得很糟糕),该问题总结在包装所有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" } ] } ]
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}