web-dev-qa-db-fra.com

Le paramètre de chaîne FromBody donne la valeur null

C’est probablement quelque chose de très fondamental, mais j’ai du mal à comprendre où j’ai tort. 

J'essaie de saisir une chaîne du corps d'un POST, mais "jsonString" n'affiche que la valeur null. Je veux aussi éviter d'utiliser un modèle, mais peut-être que ce n'est pas possible. Le morceau de code que je frappe avec PostMan est ce morceau:

[Route("Edit/Test")]
[HttpPost]
public void Test(int id, [FromBody] string jsonString)
{
    ...
}

C’est peut-être quelque chose que je ne fais pas correctement avec postman, mais j’ai essayé d’utiliser "= test" (comme indiqué dans d’autres questions posées à ce sujet) dans la section valeur du corps - section x-www-form-urlencoded la clé comme jsonString et rien. J'ai également essayé d'utiliser raw-text et raw-text/plain. Je reçois l'identifiant afin que je sache que l'URL est correcte. Toute l'aide pouvant etre apportée serait très appréciée. 

PostMan est configuré comme ceci actuellement:

POST http://localhost:8000/Edit/Test?id=111
key = id  value = 111
Body - x-www-form-urlencoded
key = jsonString  value = "=test"
21
Robert Prine

En déclarant le paramètre jsonString avec [FromBody], vous indiquez à ASP.NET Core d'utiliser le formateur d'entrée pour lier le code JSON (ou XML) fourni à un modèle. Votre test devrait donc fonctionner si vous fournissez une classe de modèle simple

public class MyModel
{
    public string Key {get; set;}
}

[Route("Edit/Test")]
[HttpPost]
public void Test(int id, [FromBody] MyModel model)
{
    ... model.Key....
}

et un JSON envoyé comme

{
    key: "value"
}

Bien sûr, vous pouvez ignorer la liaison de modèle et récupérer directement les données fournies en accédant à HttpContext.Request dans le contrôleur. La propriété HttpContext.Request.Body vous donne le flux de contenu ou vous pouvez accéder aux données du formulaire via HttpContext.Request.Forms.

Personnellement, je préfère le modèle de liaison en raison du type de sécurité.

32
Ralf Bönning

Référencement Liaison de paramètres dans l'API Web ASP.NET

Utilisation de [FromBody]

Pour forcer l'API Web à lire un type simple à partir du corps de la demande, ajoutez le [FromBody] attribut au paramètre:

[Route("Edit/Test")]
[HttpPost]
public IHttpActionResult Test(int id, [FromBody] string jsonString) { ... }

Dans cet exemple, l'API Web utilisera un formateur de type média pour lire le fichier valeur de jsonString à partir du corps de la demande. Voici un exemple de client demande.

POST http://localhost:8000/Edit/Test?id=111 HTTP/1.1
User-Agent: Fiddler
Host: localhost:8000
Content-Type: application/json
Content-Length: 6

"test"

Lorsqu'un paramètre a [FromBody], l'API Web utilise l'en-tête Content-Type pour sélectionner un formateur. Dans cet exemple, le type de contenu est "application/json" et le corps de la demande est une chaîne JSON brute (et non un objet JSON).

Dans l'exemple ci-dessus, aucun modèle n'est nécessaire si les données sont fournies au format correct dans le corps.

Pour une URL encodée, une requête ressemblerait à ceci

POST http://localhost:8000/Edit/Test?id=111 HTTP/1.1
User-Agent: Fiddler
Host: localhost:8000
Content-Type: application/x-www-form-urlencoded
Content-Length: 5

=test
32
Nkosi

Lorsque vous avez l'attribut [FromBody], la chaîne envoyée ne doit pas être une chaîne brute, mais plutôt une chaîne JSON car elle inclut les guillemets d'habillage: 

"test"

Basé sur https://weblog.west-wind.com/posts/2017/Sep/14/Accepting-Raw-Request-Body-Content-in-ASPNET-Core-API-Controllers

Une réponse chaîne similaire est vide lorsque vous utilisez FromBody dans asp.net web api

 

11
Michael Freidgeim

Tu es sur la bonne piste. 

Sur votre en-tête

Content-Type: application/x-www-form-urlencoded

Le corps de la demande POST doit être =test et rien d'autre. Pour les chaînes inconnues/variables, vous devez encoder la valeur dans l’URL de manière à ne pas échapper accidentellement à un caractère saisi.


Voir aussi Chaîne POST à l'application ASP.NET Web Api - Renvoie la valeur null

5
Igor

Je sais que cette réponse est un peu ancienne et il existe de très bonnes réponses qui résolvent déjà le problème. 

Afin d’élargir le sujet, je voudrais mentionner une dernière chose qui m’a rendue folle pendant les 4 ou 5 dernières heures.


Il est TRES TRES TRES important que l'attribut set de vos propriétés de votre classe de modèle soit activé.


Ce NE SERA PAS work (paramètre toujours nul):

/* Action code */
[HttpPost]
public Weird NOURLAuthenticate([FromBody] Weird form) {
    return form;
}
/* Model class code */
public class Weird {
    public string UserId {get;}
    public string UserPwd {get;}
}

CeciVAtravail:

/* Action code */
[HttpPost]
public Weird NOURLAuthenticate([FromBody] Weird form) {
    return form;
}
/* Model class code */
public class Weird {
    public string UserId {get; set;}
    public string UserPwd {get; set;}
}
2

Dans mon cas, j'ai oublié d'utiliser JSON.stringify (bodyStuff).

1
Eugene

Enfin, il a fonctionné après 1 heure de lutte.

Cela supprimera le problème null, obtiendra également la valeur de value1 de JSON key1 , de manière générique (pas de liaison de modèle),.

Pour un nouvel exemple d'application WebApi 2:

Facteur (ressemble exactement, comme ci-dessous):

POST    http://localhost:61402/api/values   [Send]

              Body
                   (*) raw             JSON (application/json) v

"{  \"key1\": \"value1\" }"

Le port 61402 ou url/api/values ​​above peut être différent pour vous.

ValuesController.cs

using Newtonsoft.Json;
// ..

// POST api/values
[HttpPost]
public object Post([FromBody]string jsonString)
{
    // add reference to Newtonsoft.Json
    //  using Newtonsoft.Json;

    // jsonString to myJsonObj
    var myJsonObj = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(jsonString);

    // value1 is myJsonObj[key1]
    var valueOfkey1 = myJsonObj["key1"];

    return myJsonObj;
}

Tout va bien pour le moment, je ne sais pas si une liaison de modèle à une classe est requise si j'ai des sous-clés ou si DeserializeObject peut fonctionner sur une sous-clé.

0