MVC控制器:从HTTP身体得到JSON对象? [英] MVC controller : get JSON object from HTTP body?

查看:133
本文介绍了MVC控制器:从HTTP身体得到JSON对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有这有时可能会(http://server.com/events/),由第三方发布到我们的具体URL的JSON活动的MVC(MVC4)应用程序。 JSON的事件是在HTTP POST的身体和身体是严格JSON(内容类型:应用程序/ JSON - 不是一个表单提交使用JSON在一些串场)。

我怎样才能收到控制器的体内JSON身体?我尝试以下,但没有得到任何东西。

:当我说的没有得到任何的我的意思是jsonBody总是空不管我是否把它定义为对象字符串

  [HttpPost]
    //这个映射到http://server.com/events/
    //为什么总是jsonBody空?!
    公众的ActionResult指数(INT?ID,串jsonBody)
    {
        //这里做的东西
    }

请注意,我知道如果我给声明一个强类型的输入参数的方法,MVC确实全解析和过滤即。

  //这个测​​试工作,jsonBody具有有效的JSON数据
    //我可以反序列化使用JSON.net
    公众的ActionResult指数(INT?ID,ClassType847 jsonBody){...}

然而,我们得到的JSON是非常不同的,所以我们不希望定义(和维护)数百个不同类别的每个JSON变体。

我通过以下测试这种卷曲命令(这里的JSON的一个变体)

 卷曲-i -H主机:本地主机-H内容类型:应用程序/ JSON-X POST的http://本地主机/ -d{创建/事件:1326853478,数据:{对象:{NUM_OF_ERRORS:123,FAIL_COUNT:3}}}


解决方案

看来,如果


  • 内容类型:应用程序/ JSON

  • 如果POST身体没有紧密结合控制器的输入对象类

然后MVC并没有真正的POST体绑定到任何特定的类。你也不能只取POST身体为的ActionResult(在另一个答案的建议)的参数。很公平。您需要从请求流自己和处理它把它拿来。

  [HttpPost]
    公众的ActionResult指数(INT?ID)
    {
        流REQ = Request.InputStream;
        req.Seek(0,System.IO.SeekOrigin.Begin);
        JSON字符串=新的StreamReader(REQ).ReadToEnd();        InputClass输入= NULL;
        尝试
        {
            //假设JSON.net/Newtonsoft库从http://json.$c$cplex.com/
            输入= JsonConvert.DeserializeObject< InputClass>(JSON)
        }        赶上(异常前)
        {
            //尝试和处理畸形的POST体
            返回新的HTTPStatus codeResult(的HTTPStatus code.BadRequest);
        }        //做东西    }

We have an MVC (MVC4) application which at times might get a JSON events POSTed from a 3rd party to our specific URL ("http://server.com/events/"). The JSON event is in the body of the HTTP POST and the body is strictly JSON (Content-Type: application/json - not a form-post with JSON in some string field).

How can I receive the JSON body inside the controller's body? I tried the following but didn't get anything

[Edit]: When I say didn't get anything I meant that jsonBody is always null regardless of whether I define it as Object or string.

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

Note that I know if I give declare the method with a strongly typed input parameter, MVC does the whole parsing and filtering i.e.

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

However, the JSON we get is very varied, so we don't want to define (and maintain) hundreds of different classes for each JSON variant.

I'm testing this by the following curl command (with one variant of the JSON here)

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

解决方案

It seems that if

  • Content-Type: application/json and
  • if POST body isn't tightly bound to controller's input object class

Then MVC doesn't really bind the POST body to any particular class. Nor can you just fetch the POST body as a param of the ActionResult (suggested in another answer). Fair enough. You need to fetch it from the request stream yourself and process it.

    [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

    }

这篇关于MVC控制器:从HTTP身体得到JSON对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆