MVC控制器:从HTTP主体获取JSON对象?

Dee*_*101 64 asp.net-mvc post json

我们有一个MVC(MVC4)应用程序,有时可能会将第三方发布的JSON事件发送到我们的特定URL(" http://server.com/events/ ").JSON事件位于HTTP POST的主体中,正文是严格的JSON(Content-Type: application/json- 不是某些字符串字段中带有JSON的表单).

如何在控制器的主体内接收JSON主体?我尝试了以下但没有得到任何东西

[编辑]:当我说没有得到任何东西时,我的意思是jsonBody始终为null,无论我是将其定义为Objectstring.

[HttpPost]
// this maps to http://server.com/events/
// why is jsonBody always null ?!
public ActionResult Index(int? id, string jsonBody)
{
    // Do stuff here
}
Run Code Online (Sandbox Code Playgroud)

请注意,我知道如果我使用强类型输入参数声明方法,MVC会进行整个解析和过滤,即

// this tested to work, jsonBody has valid json data 
// that I can deserialize using JSON.net
public ActionResult Index(int? id, ClassType847 jsonBody) { ... }
Run Code Online (Sandbox Code Playgroud)

但是,我们获得的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 }}}
Run Code Online (Sandbox Code Playgroud)

Dee*_*101 134

似乎如果

  • 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

}
Run Code Online (Sandbox Code Playgroud)

更新:

对于Asp.Net Core,您必须[FromBody]在控制器操作中为复杂的JSON数据类型添加atram名称旁边的attrib:

[HttpPost]
public ActionResult JsonAction([FromBody]Customer c)
Run Code Online (Sandbox Code Playgroud)

此外,如果您想以字符串形式访问请求正文以自行解析,则应使用Request.Body而不是Request.InputStream:

Stream req = Request.Body;
req.Seek(0, System.IO.SeekOrigin.Begin);
string json = new StreamReader(req).ReadToEnd();
Run Code Online (Sandbox Code Playgroud)


Chu*_*ang 6

使用Request.Form来获得数据

控制器:

    [HttpPost]
    public ActionResult Index(int? id)
    {
        string jsonData= Request.Form[0]; // The data from the POST
    }
Run Code Online (Sandbox Code Playgroud)

我写这个试试

视图:

<input type="button" value="post" id="btnPost" />

<script type="text/javascript">
    $(function () {
        var test = {
            number: 456,
            name: "Ryu"
        }
        $("#btnPost").click(function () {
            $.post('@Url.Action("Index", "Home")', JSON.stringify(test));
        });
    });
</script>
Run Code Online (Sandbox Code Playgroud)

并写入Request.Form[0]Request.Params[0]在控制器中可以获取数据.

我不写<form> tag在视野中.

  • HTML POST主体中没有任何形式-HTML POST主体为纯json。因此,Request.Form [0] = null(其计数为0)。 (2认同)