Asp.net-Mvc
MVC 控制器:從 HTTP 主體獲取 JSON 對象?
我們有一個 MVC (MVC4) 應用程序,它有時可能會從第 3 方獲取一個 JSON 事件 POST 到我們的特定 URL(“ <http://server.com/events/> ”)。JSON 事件在 HTTP POST 的正文中,並且正文是嚴格的 JSON(
Content-Type: application/json-不是在某些字元串欄位中帶有 JSON 的表單發布)。如何在控制器主體內接收 JSON 主體?我嘗試了以下但沒有得到任何東西
[編輯]:當我說沒有得到任何東西時,我的意思是 jsonBody 始終為空,無論我是否將其定義為
Object或string。[HttpPost] // this maps to http://server.com/events/ // why is jsonBody always null ?! public ActionResult Index(int? id, string jsonBody) { // Do stuff here }請注意,我知道如果我用強類型輸入參數聲明方法,MVC 會完成整個解析和過濾,即
// this tested to work, jsonBody has valid json data // that I can deserialize using JSON.net public ActionResult Index(int? id, ClassType847 jsonBody) { ... }然而,我們得到的 JSON 是多種多樣的,所以我們不想為每個 JSON 變體定義(和維護)數百個不同的類。
我正在通過以下
curl命令對此進行測試(此處使用 JSON 的一種變體)curl -i -H "Host: localhost" -H "Content-Type: application/json" -X POST http://localhost/events/ -d '{ "created": 1326853478, "data": { "object": { "num_of_errors": 123, "fail_count": 3 }}}
好像如果
Content-Type: application/json和- 如果 POST 主體沒有緊密綁定到控制器的輸入對像類
然後 MVC 並沒有真正將 POST 主體綁定到任何特定的類。您也不能只獲取 POST 正文作為 ActionResult 的參數(在另一個答案中建議)。很公平。您需要自己從請求流中獲取並處理它。
[HttpPost] public ActionResult Index(int? id) { Stream req = Request.InputStream; req.Seek(0, System.IO.SeekOrigin.Begin); string json = new StreamReader(req).ReadToEnd(); InputClass input = null; try { // assuming JSON.net/Newtonsoft library from http://json.codeplex.com/ input = JsonConvert.DeserializeObject<InputClass>(json) } catch (Exception ex) { // Try and handle malformed POST body return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } //do stuff }更新:
對於 Asp.Net Core,
[FromBody]對於復雜的 JSON 數據類型,您必須在控制器操作中的參數名稱旁邊添加屬性:[HttpPost] public ActionResult JsonAction([FromBody]Customer c)此外,如果您想以字元串的形式訪問請求正文以自己解析它,您應該使用
Request.Body而不是Request.InputStream:Stream req = Request.Body; req.Seek(0, System.IO.SeekOrigin.Begin); string json = new StreamReader(req).ReadToEnd();