. net用于包装JsonResult Actions响应的过滤器
本文关键字:响应 过滤器 Actions JsonResult 用于 包装 net | 更新日期: 2023-09-27 18:03:48
我已经构建了一个Web API应用程序并发现了一个问题(目前在我的代码中处理得很糟糕),这个问题总结为包装所有从所有API操作返回的Json
对象与自定义节点(根)。
。e:我有这个json (array)响应:
[
{
"Category": "Pages",
"Users": [
{
"ID": "1",
"Fname": "Foo",
"Lname": "Bar"
}
]
}
]
And Need this response:
{
"Object": {
"Body": [
{
"Category": "Pages",
"Users": [
{
"ID": "1",
"Fname": "Foo",
"Lname": "Bar"
}
]
}
]
}
}
这里我将响应包装在{"Object":{"Body": <Response Here>}}
我需要它应用于所有API Json响应类型的Array
。
对于简单的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"
假设这里是您要查找的内容:
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类(并添加返回该类的扩展方法)
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}}; }
}
}