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

时间:2012-10-24 01:37:23

标签: asp.net-mvc json post

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

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

[编辑] :当我说没有得到任何内容时我的意思是jsonBody始终为null,无论我将其定义为Object还是{ {1}}。

string

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

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

但是,我们得到的JSON非常多样,因此我们不希望为每个JSON变体定义(和维护)数百个不同的类。

我正在通过以下// this tested to work, jsonBody has valid json data // that I can deserialize using JSON.net public ActionResult Index(int? id, ClassType847 jsonBody) { ... } 命令对此进行测试(此处使用JSON的一个变体)

curl

5 个答案:

答案 0 :(得分:121)

似乎是

  • 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

}

<强>更新

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

[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();

答案 1 :(得分:6)

使用Request.Form获取数据

控制器:

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

我写这个试试

查看:

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

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

我不会在视图中写<form> tag

答案 2 :(得分:0)

您可以将json字符串作为ActionResult的参数,然后使用JSON.Net

序列化它

HERE正在展示一个例子


为了以序列化形式接收它作为控制器操作的参数,您必须编写自定义模型绑定器或Action过滤器(OnActionExecuting),以便将json字符串序列化到您喜欢的模型中并且可用在控制器主体内部使用。


HERE是使用动态对象

的实现

答案 3 :(得分:0)

一旦你定义了一个类(MyDTOClass),表明你希望收到它,它应该像...一样简单......

public ActionResult Post([FromBody]MyDTOClass inputData){
 ... do something with input data ...
}

Thx to Julias:

Parsing Json .Net Web Api

确保您的请求与http标头一起发送:

Content-Type:application / json

答案 4 :(得分:0)

我一直在尝试获取我的 ASP.NET MVC控制器,以解析我使用Postman提交给它的某些模型。

我需要以下各项才能使其正常工作:

  • 控制器动作

    [HttpPost]
    [PermitAllUsers]
    [Route("Models")]
    public JsonResult InsertOrUpdateModels(Model entities)
    {
        // ...
        return Json(response, JsonRequestBehavior.AllowGet);
    }
    
  • 模型类

    public class Model
    {
        public string Test { get; set; }
        // ...
    }
    
  • 邮递员请求的标头,特别是Content-Type

    postman headers

  • 请求正文中的
  • json

    enter image description here