Контроллер MVC: получить объект JSON из тела HTTP?



у нас есть приложение MVC (MVC4), которое иногда может получать события JSON, отправленные от третьей стороны на наш конкретный URL ( " http://server.com/events/"). событие JSON находится в теле сообщения HTTP, и тело строго JSON (Content-Type: application/json - не форма-сообщение с JSON в некотором строковом поле).



как я могу получить тело JSON внутри тела контроллера? Я попробовал следующее, Но ничего не получил



[Edit]: когда я говорю ничего не понял я имел в виду, что jsonBody всегда null независимо от того, определяю ли я его как Object или 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 делает весь разбор и фильтрацию, т. е.



// 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 }}}
632   4  

4 ответов:

Кажется, что если

  • Content-Type: application/json и
  • если тело сообщения не тесно связано с входным классом объекта контроллера

тогда MVC на самом деле не привязывает тело сообщения к какому-либо определенному классу. Вы также не можете просто получить тело сообщения как параметр 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

}

использовать Request.Form чтобы получить данные

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

Я пишу это, чтобы попробовать

View:

<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 в поле зрения.

Как только вы определяете класс (MyDTOClass), указывающий, что вы ожидаете получить, это должно быть так же просто, как...

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

Thx к Julias:

Разбор Json .Net Web Api

убедитесь, что ваш запрос отправляется с заголовком http:

Content-Type: application / json

вы можете получить строку JSON в качестве параметра вашего ActionResult а затем сериализовать его с помощью JSON.Net

здесь пример отображается


чтобы получить его в сериализованной форме в качестве параметра действия контроллера, вы должны либо написать пользовательскую привязку модели, либо фильтр действий (OnActionExecuting), чтобы строка json сериализовалась в модель по вашему вкусу и была доступна внутри корпуса регулятора.


здесь - это реализация с использованием динамического объекта

Comments

    Ничего не найдено.