我们有一个MVC(MVC4)应用程序,有时可能会得到一个JSON事件从第三方POST到我们的特定URL(“http://server.com/events/”)。 JSON事件在HTTP POST的正文中,正文是严格的JSON(Content-Type:application / json – 不是在某些字符串字段中使用JSON的表单 – post)。
如何在控制器的主体内部接收JSON主体?我试过下面但没有得到任何东西
[编辑]:当我说没有得到任何东西我的意思是jsonBody总是null,无论我定义为对象还是字符串。
[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 }