Контроллер MVC: получить объект JSON из тела HTTP?
у нас есть приложение MVC (MVC4), которое время от времени может получать события JSON, размещенные от третьей стороны на наш конкретный URL ("http://server.com/events/"). Событие JSON находится в теле HTTP POST, и тело строго 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 }}}
4 ответов
Кажется, что если
-
Content-Type: application/json
и - если тело POST не тесно связано с входным классом объекта контроллера
тогда MVC действительно не привязывает тело 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
}
использовать 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]
in контроллер может получить данные.
Я не пишу <form> tag
в поле зрения.
Как только вы определяете класс (MyDTOClass), указывающий, что вы ожидаете получить, он должен быть таким же простым, как...
public ActionResult Post([FromBody]MyDTOClass inputData){
... do something with input data ...
}
Thx Джулиасу:
Синтаксический Анализ JSON .Net Web Api
убедитесь, что ваш запрос отправлен с заголовком http:
тип контента: application / json
вы можете получить строку JSON в качестве параметра вашего ActionResult
и затем сериализуйте его, используя JSON.Net
здесь показывается пример
чтобы получить его в сериализованной форме в качестве параметра действия контроллера, вы должны либо написать пользовательскую привязку модели, либо фильтр действий (OnActionExecuting), чтобы строка json сериализовалась в модель по вашему вкусу и была доступна внутри корпуса регулятора.
здесь является реализацией с использованием динамического объекта