Nous avons une application MVC (MVC4) qui peut parfois recevoir un événement JSON POST d'une tierce partie sur notre URL spécifique (" http://server.com/events/ "). L'événement JSON est dans le corps du HTTP POST et le corps est strictement JSON (Content-Type: application/json
- pas un formulaire-post avec JSON dans un champ de chaîne).
Comment puis-je recevoir le corps JSON à l'intérieur du corps du contrôleur? J'ai essayé ce qui suit mais je n'ai rien eu
[Edit]: Quand je dis rien obtenu je voulais dire que jsonBody est toujours nul, que je le définisse comme Object
ou string
.
[HttpPost]
// this maps to http://server.com/events/
// why is jsonBody always null ?!
public ActionResult Index(int? id, string jsonBody)
{
// Do stuff here
}
Notez que si je donne à déclarer la méthode avec un paramètre d’entrée fortement typé, MVC effectue l’ensemble de l’analyse et du filtrage, c.-à-d.
// this tested to work, jsonBody has valid json data
// that I can deserialize using JSON.net
public ActionResult Index(int? id, ClassType847 jsonBody) { ... }
Cependant, le JSON que nous obtenons est très varié, nous ne souhaitons donc pas définir (ni maintenir) des centaines de classes différentes pour chaque variante JSON.
Je teste cela avec la commande curl
suivante (avec une variante du JSON ici)
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 }}}
Il semble que si
Content-Type: application/json
etEnsuite, MVC ne lie pas vraiment le corps POST à une classe particulière. Vous ne pouvez pas non plus simplement extraire le corps POST en tant que paramètre de ActionResult (suggéré dans une autre réponse). C'est suffisant. Vous devez le récupérer vous-même à partir du flux de demandes et le traiter.
[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
}
Mettre à jour:
pour Asp.Net Core, vous devez ajouter [FromBody]
attrib à côté de votre nom de paramètre dans l'action de votre contrôleur pour les types de données JSON complexes:
[HttpPost]
public ActionResult JsonAction([FromBody]Customer c)
De plus, si vous souhaitez accéder au corps de la requête sous forme de chaîne pour l'analyser vous-même, vous devez utiliser Request.Body
au lieu de Request.InputStream
:
Stream req = Request.Body;
req.Seek(0, System.IO.SeekOrigin.Begin);
string json = new StreamReader(req).ReadToEnd();
utiliser Request.Form
pour obtenir les données
Manette:
[HttpPost]
public ActionResult Index(int? id)
{
string jsonData= Request.Form[0]; // The data from the POST
}
J'écris ceci pour essayer
Vue:
<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>
et écrire Request.Form[0]
ou Request.Params[0]
dans le contrôleur peut obtenir les données.
Je n'écris pas <form> tag
en vue.
Une fois que vous avez défini une classe (MyDTOClass) indiquant ce que vous attendez, elle devrait être aussi simple que ...
public ActionResult Post([FromBody]MyDTOClass inputData){
... do something with input data ...
}
Thx à Julias:
Assurez-vous que votre demande est envoyée avec l'en-tête http:
Type de contenu: application/json
J'ai essayé d'obtenir que mon contrôleur ASP.NET MVC analyse un modèle que je lui ai soumis à l'aide de Postman .
J'avais besoin de ce qui suit pour le faire fonctionner:
action du contrôleur
[HttpPost]
[PermitAllUsers]
[Route("Models")]
public JsonResult InsertOrUpdateModels(Model entities)
{
// ...
return Json(response, JsonRequestBehavior.AllowGet);
}
une classe de modèles
public class Model
{
public string Test { get; set; }
// ...
}
en-têtes pour la demande de Postman, plus précisément, Content-Type
json dans le corps de la demande
vous pouvez obtenir la chaîne json en tant que paramètre de votre ActionResult
puis la sérialiser à l'aide de JSON.Net
ICI un exemple est montré
pour le recevoir sous forme sérialisée en tant que paramètre de l'action du contrôleur, vous devez écrire un classeur de modèle personnalisé ou un filtre Action (OnActionExecuting) afin que la chaîne json soit sérialisée dans le modèle de votre choix et disponible dans le contrôleur corps pour l'utilisation.
HERE est une implémentation utilisant l'objet dynamique