Asp.net-Mvc

MVC 控制器:從 HTTP 主體獲取 JSON 對象?

  • October 24, 2012

我們有一個 MVC (MVC4) 應用程序,它有時可能會從第 3 方獲取一個 JSON 事件 POST 到我們的特定 URL(“ <http://server.com/events/> ”)。JSON 事件在 HTTP POST 的正文中,並且正文是嚴格的 JSON(Content-Type: application/json-不是在某些字元串欄位中帶有 JSON 的表單發布)。

如何在控制器主體內接收 JSON 主體?我嘗試了以下但沒有得到任何東西

[編輯]:當我說沒有得到任何東西時,我的意思是 jsonBody 始終為空,無論我是否將其定義為Objectstring

[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&lt;InputClass&gt;(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();

引用自:https://stackoverflow.com/questions/13041808