2017-02-10 60 views
1

我们有一个ASP.NET应用程序。我们不能编辑控制器的源代码。但是我们可以实现ActionFilter。ASP.NET。如何修改返回的JSON(actionfilter)

我们的控制器操作方法之一返回JSON。有没有可能在ActionFilter中修改它?我们需要添加一个属性到一个返回的对象。

也许,其他方式来实现它?

+0

我认为在理论上'OnResultExecuted'应该在ActionFilter中做你想做的事情。它可以通过context.Result访问结果(https://msdn.microsoft.com/en-us/library/system.web.mvc.resultexecutedcontext.result(v=vs.118).aspx#P:System。 Web.Mvc.ResultExecutedContext.Result),它应该允许您根据需要操作它。这听起来不像是一种很好的方法,但如果你不能改变控制器,并且大概不能改变控制器所调用的任何工厂,那么这听起来就像是你唯一的选择。我没有自己做过,所以不能肯定地说它会起作用... – Chris

+0

你是如何得到JSON的?请向我们显示代码,以便我们提供帮助。 – jomsk1e

+0

您是否可以不只是创建一个新动作,调用旧动作然后添加该字段并传递新的结果? – Milney

回答

4

发现这个有趣的事情和@Chris提到的,虽然从概念上说我知道这会起作用,但我从来没有试过这个,因此想到给它一个镜头。我不确定这是否是一种优雅/正确的方式,但这对我有效。 (我尝试添加动态使用ActionResultAge属性)

[PropertyInjector("Age", 12)] 
    public ActionResult Index() 
    { 
     return Json(new { Name = "Hello World" }, JsonRequestBehavior.AllowGet); 
    } 

和过滤器:

public class PropertyInjector : ActionFilterAttribute 
{ 
    string key; 
    object value; 
    public PropertyInjector(string key, object value) 
    { 
     this.key = key; 
     this.value = value; 
    } 
    public override void OnActionExecuted(ActionExecutedContext filterContext) 
    { 
     var jsonData = ((JsonResult)filterContext.Result).Data; 
     JObject data = JObject.FromObject(jsonData); 
     data.Add(this.key,JToken.FromObject(this.value)); 

     filterContext.Result = new ContentResult { Content = data.ToString(), ContentType = "application/json" }; 

     base.OnActionExecuted(filterContext); 
    } 
} 

更新

如果不是动态的数据将被注入,然后直接删除过滤器构造函数和硬编码键值&,然后可以在不编辑控制器的情况下全局注册过滤器 GlobalFilters.Filters.Add(new PropertyInjector());

+0

当然,这确实需要编辑控制器才能添加属性? – Milney

+1

@Milney如果它不是动态的数据将被注入,然后过滤器可以在全球注册而不触及控制器 – Developer

+1

@Milney全球注册过滤器,有它检查的要求,以确保它是所需的控制器的动作,并执行,如果需要的变化是。 – Nkosi