2016-08-24 38 views
2

我已經建立了一個的Web API應用程序,發現了一個問題(目前在我的代碼處理不好),在包裝從所有API操作返回所有Json對象概括的問題自定義節點(根)。淨過濾器用於包裝JsonResult舉動的反應

即:我有此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"

+1

[在MVC 4正確的JSON序列]的可能的複製(http://stackoverflow.com/questions/17244774/proper-json-serialization-in-mvc-4) – MrClan

+0

你需要一個**定製JSON序列化器**而不是過濾器。 – MrClan

回答

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

感謝它的完美 –

+0

如果我需要爲Json對象(不是Json對象數組)創建不同的包裝,就像{「Body」:{「a」:1,「b」:2}並保持數組相同 –

+0

@ MoamenNaanou將'Data = new {Object = new {Body = jsonRes.Data}}'行更改爲任何您喜歡的結構。 –

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