MVC 控制器:从 HTTP 正文获取 JSON 对象? [英] MVC controller : get JSON object from HTTP body?

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

问题描述

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

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).

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

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

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

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

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

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) { ... }

然而,我们得到的 JSON 非常多样化,所以我们不想为每个 JSON 变体定义(和维护)数百个不同的类.

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.

我正在通过以下 curl 命令(此处使用 JSON 的一种变体)对此进行测试

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

推荐答案

看来如果

  • Content-Type: application/json
  • 如果 POST 主体没有与控制器的输入对象类紧密绑定

然后 MVC 并没有真正将 POST 主体绑定到任何特定的类.您也不能只获取 POST 正文作为 ActionResult 的参数(在另一个答案中建议).很公平.您需要自己从请求流中获取并处理它.

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

}

更新:

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

for Asp.Net Core, you have to add [FromBody] attrib beside your param name in your controller action for complex JSON data types:

[HttpPost]
public ActionResult JsonAction([FromBody]Customer c)

另外,如果你想访问请求体作为字符串来自己解析它,你应该使用Request.Body而不是Request.InputStream:

Also, if you want to access the request body as string to parse it yourself, you shall use Request.Body instead of Request.InputStream:

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

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

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