Depuis la mise à niveau vers RC pour WebAPI, j'ai un problème étrange lors de l'appel de POST sur mon WebAPI. Je suis même revenu à la version de base générée sur un nouveau projet. Alors:
public void Post(string value)
{
}
et appeler de Fiddler:
Header:
User-Agent: Fiddler
Host: localhost:60725
Content-Type: application/json
Content-Length: 29
Body:
{
"value": "test"
}
Lorsque je débogue, la chaîne "value" n'est jamais affectée à. C'est toujours NULL. Quelqu'un a ce problème?
(J'ai d'abord vu le problème avec un type plus complexe)
Le problème n'est pas uniquement lié à ASP.NET MVC 4, le même problème se produit pour un nouveau projet ASP.NET MVC 3 après l'installation de RC
c#
.net
asp.net-web-api
asp.net-web-api-routing
ianrathbone
la source
la source
Réponses:
Comme vous n'avez qu'un seul paramètre, vous pouvez essayer de le décorer avec l'
[FromBody]
attribut, ou changer la méthode pour accepter un DTO avec une valeur en tant que propriété, comme je l'ai suggéré ici: Liaison de paramètres MVC4 RC WebApiMISE À JOUR: Le site officiel ASP.NET a été mis à jour aujourd'hui avec une excellente explication: https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/sending-html-form-data-part- 1
En résumé, lors de l'envoi d'un seul type simple dans le corps, envoyez uniquement la valeur préfixée par un signe égal (=), par exemple body:
=test
la source
=
en face n'a jamais fonctionné pour moi, jusqu'à ce que je suive les conseils de Jim dans son commentaire (pas en tant qu'objet JSON) et que cela fonctionne. C'est la clé! Je n'aime vraiment pas à quel point WebAPI est difficile.:(
). Vous devez vraiment ajouter un support pour le format que les gens s'attendent à ce qu'il accepte.Je me suis gratté la tête aujourd'hui.
Ma solution est de changer le
[FromBody]
en aHttpRequestMessage
, essentiellement en remontant la pile HTTP.Dans mon cas, j'envoie des données à travers le fil qui est zippé json qui est ensuite base64'd. Tout cela à partir d'une application Android.
La signature originale de mon point de terminaison Web ressemblait à ceci (en utilisant
[FromBody]
):Mon correctif pour ce problème était de revenir à l'utilisation d'un
HttpRequestMessage
pour la signature de mon point de terminaison.Vous pouvez ensuite accéder aux données de publication à l'aide de cette ligne de code:
Cela fonctionne et vous permet d'accéder aux données brutes des messages intacts. Vous n'avez pas besoin de jouer avec le violoneux en mettant un signe = au début de votre chaîne ou en changeant le type de contenu.
En passant, j'ai d'abord essayé de suivre l'une des réponses ci-dessus qui consistait à changer le type de contenu en: "Content-Type: application / x-www-form-urlencoded". Pour les données brutes, c'est un mauvais conseil car il supprime les caractères +.
Donc une chaîne base64 qui commence comme ceci: "MQ0AAB + LCAAAAAA" finit comme ceci "MQ0AAB LCAAAAAA"! Pas ce que tu veux.
Un autre avantage de l'utilisation
HttpRequestMessage
est que vous avez accès à tous les en-têtes http depuis votre point de terminaison.la source
HttpRequestMessage request
de la signature de méthode, car vous l'avez déjà déjà. Dans le corps de la méthode, il est accessible sur l'Request
objet. par exempleRequest.Content.ReadAsStringAsync().Result;
Je viens d'avoir ce problème avec Fiddler. Le problème était que je n'avais pas précisé
Content-Type
.Essayez d'inclure un en-tête pour
Content-Type
dans votre demande POST.Alternativement, selon les commentaires ci-dessous, vous devrez peut-être inclure un en-tête JSON
la source
contentType: "application/x-www-form-urlencoded; charset=UTF-8"
, pour un exemple complet, voir Complete Cient and ServerJ'ai également rencontré ce problème, et voici comment j'ai résolu mon problème
code webapi:
code client:
la source
some value
, alorsdata
est nulle.J'utilisais
Postman
et je faisais la même erreur .. en passant l'value
objet as json au lieu de la chaîneClairement, celui ci-dessus est incorrect lorsque le paramètre api est de type chaîne.
Donc, passez simplement la chaîne entre guillemets dans le corps de l'API:
la source
JSON.stringify
me faisait[frombody]
êtrenull
. Après avoir défini le champ de données sur une valeur de chaîne (c'est-à-dire une chaîne json), cela a fonctionné.Essayez de créer une classe pour servir de modèle de données, puis envoyez un objet JSON avec des propriétés correspondant aux propriétés de votre classe de modèle de données. (Remarque: j'ai testé cela et cela fonctionne avec le plus récent MVC 4 RC 2012 que je viens de télécharger aujourd'hui).
L'objet JSON ci-dessous est envoyé dans le corps HTTP-POST, le type de contenu est application / json
Je crois que la raison pour laquelle vous devez créer une classe de modèle de données est que les valeurs simples sont supposées provenir des paramètres url et qu'une seule valeur complexe est supposée provenir du corps. Ils ont les attributs
[FromBody]
et[FromUrl]
, mais l'utilisation[FromBody] string value
n'a toujours pas fonctionné pour moi. On dirait qu'ils travaillent toujours sur beaucoup de bugs, donc je suis sûr que cela va changer à l'avenir.Edit: Got XML pour fonctionner dans le corps. Le sérialiseur XML par défaut a été remplacé par DataContractSerializer au lieu de XmlSerializer. Mettre la ligne suivante dans mon fichier Global.asax a résolu ce problème ( référence )
la source
Après quelques essais, je pense que le comportement par défaut est correct et qu'il n'y a rien à pirater.
La seule astuce est: si votre argument de méthode post est
string
comme ci-dessous, vous devez envoyer une chaîne simple avec des guillemets doubles dans le corps (lorsque vous utilisez ajax ou postman), par exemple,Sinon, si vous envoyez une chaîne json dans le corps du message sans guillemets externes et sans guillemets internes échappés, elle doit pouvoir être analysée dans la classe du modèle (le type d'argument), par exemple,
{"a":1, "b":2}
la source
Je cherchais une solution à ce problème depuis quelques minutes maintenant, je vais donc partager ma solution.
Si vous postez un modèle, votre modèle doit avoir un constructeur vide / par défaut, sinon le modèle ne peut pas être créé, évidemment. Soyez prudent lors de la refactorisation. ;)
la source
Cela a fonctionné pour moi:
Créez une classe C # DTO, avec une propriété pour chaque attribut que vous souhaitez passer de jQuery / Ajax
Définissez la méthode de l'API Web:
Appelez l'API Web en tant que telle:
la source
Pour ceux qui ont le même problème avec Swagger ou Postman que moi, si vous passez un attribut simple sous forme de chaîne dans un message, même avec le "ContentType" spécifié, vous obtiendrez toujours une valeur nulle.
Passer juste:
MyValue
Va entrer dans le contrôleur comme nul.
Mais si vous réussissez:
"MyValue"
La valeur ira bien.
Les citations ont fait la différence ici. Bien sûr, cela ne concerne que Swagger et Postman. Par exemple, dans une application Frontend utilisant Angular, cela devrait être résolu automatiquement par le framework.
la source
J'ai eu le même problème et j'ai découvert qu'en changeant le type de contenu en "application / json", je n'ai pas résolu le problème. Cependant, "application / json; charset = utf-8" a fonctionné.
la source
J'ai eu un problème similaire où l'objet de demande pour ma méthode d'API Web était toujours nul. J'ai remarqué que puisque le nom de l'action du contrôleur était préfixé avec "Get", l'API Web a traité cela comme un HTTP GET plutôt que comme un POST. Après avoir renommé l'action du contrôleur, cela fonctionne maintenant comme prévu.
la source
Avec Angular, j'ai pu transmettre des données dans ce format:
Et dans Web API Controler:
Alternativement, je pourrais également publier des données JSON comme ceci:
Et, dans le contrôleur, acceptez un type de classe comme celui-ci:
Dans les deux cas, si vous avez une classe publique établie dans l'API, postez JSON, sinon postez '=' + JSON.stringify ({..: ..., ..: ...})
la source
Dans mon cas, le problème était que le paramètre était une chaîne et non un objet, j'ai changé le paramètre pour être JObject de Newsoft.Json et cela fonctionne.
la source
Ajout d'une ligne
à la fin de la fonction
protected void Application_Start()
dans Global.asax.cs a résolu un problème similaire pour moi dans ASP.NET MVC3.la source
Si vous utilisez un DataContractSerializer pour votre formateur Xml ou JSON Formatter, vous devez vous en débarrasser. J'avais ceci dans mon fichier WebApiConfig:
Je commente simplement
jsonFormatter.UseDataContractJsonSerializer = true;
et mon paramètre d'entrée n'est plus nul. Merci à 'Despertar' de m'avoir donné un indice.la source
Si vous êtes sûr de votre JSON envoyé, vous devez soigneusement suivre votre API:
Microsoft.AspNet.WebApi.Tracing
packageconfig.EnableSystemDiagnosticsTracing();
la méthodeWebApiConfig
inside classRegister
.Regardez maintenant la sortie de débogage et vous trouverez probablement une
ModelState
entrée de journal non valide .Si
ModelState
n'est pas valide, vous pouvez trouver la vraie cause dans sonErrors
:Personne ne peut même deviner une telle exception:
la source
J'ai eu le même problème d'obtention de null en tant que paramètre, mais il était lié aux gros objets. Il s'est avéré que le problème était lié à la longueur maximale d'IIS. Il peut être configuré dans web.config.
Je me demande pourquoi l'API Web a supprimé l'erreur et envoie des objets nuls à mes API. J'ai trouvé l'erreur en utilisant Microsoft.AspNet.WebApi.Tracing.
la source
JSON.stringify (...) a résolu mes problèmes
la source
Je sais que ce n'est pas une réponse à cette question, mais je l'ai rencontrée lors de la recherche d'une solution à mon problème.
Dans mon cas, le type complexe n'était pas lié mais je ne faisais pas de POST, je faisais un GET avec des paramètres de chaîne de requête. La solution était d'ajouter [FromUri] à l'argument:
la source
J'ai eu le même problème à Fiddler. J'avais déjà
Content-Type: application/json; charset=utf-8
ouContent-Type: application/json
dans l'en-tête de demande.Mon corps de la demande a également été une chaîne de caractères, et Fiddler j'avais écrit:
{'controller':'ctrl'}
. Cela a fait que le paramètre de chaîne dans ma méthode POST soitnull
.Correction : n'oubliez pas d'utiliser des guillemets, indiquant ainsi une chaîne. Autrement dit, je l'ai corrigé en écrivant
"{'controller':'ctrl'}"
. (Remarque: lors de l'écriture de JSON, assurez-vous d'utiliser des apostrophes ou échappez aux guillemets comme ceci:)"{\"controller\":\"ctrl\"}"
.la source
Le moyen le plus simple que j'ai trouvé pour gérer un objet JSON simple que je passe dans MVC 6 est d'obtenir le type du paramètre post comme NewtonSoft jObject:
la source
[FromBody] object body, [FromHeader(Name="Content-Type")] string bodyMediaType
) pourrait mieux fonctionner car la vérificationbodyMediaType == "application.json"
avant de lancer le corps sur JObject offre une opportunité pour les alternatives.La meilleure solution pour moi est de passer au HTTP complet comme ci-dessous:
puis désérialisation de la chaîne à l'objet que vous attendez dans le corps du message. Pour moi, WS_OpenSession est une classe qui contenait sessionid, user et key.
Vous pouvez à partir de là utiliser l'objet param et accéder à ses propriétés.
Très très efficace.
J'ai dit provenir de cette URL:
http://bizcoder.com/posting-raw-json-to-web-api
la source
Pour les types complexes, l'API Web essaie de lire la valeur dans le corps du message, à l'aide d'un formateur de type média.
Veuillez vérifier si vous avez obtenu un
[Serializable]
attribut décorant votre classe de modèle.Supprimez l'attribut pour voir s'il fonctionne. Cela a fonctionné pour moi.
la source
Je suis un peu en retard à la fête, mais toute personne tombant sur une valeur NULL a réussi lors de l'utilisation d'un contrôleur, ajoutez simplement "=" au début de votre demande POST.
Le contrôleur a également transmis une valeur NULL lorsque j'ai utilisé l' application / json Content-Type. Notez le type de contenu "application / x-www-form-urlencoded" ci-dessous. Le type de retour de l'API est cependant "application / json".
la source
peu importe le type de valeur que vous souhaitez publier, placez-le simplement entre guillemets, pour l'obtenir sous forme de chaîne. Pas pour les types complexes.
javascript:
c #:
la source
Si vous mettez l'annotation [FromBody] et que vous avez un objet Dto en tant que paramètre de votre méthode et que vous n'êtes toujours pas en mesure de passer les données, commencez à chercher dans les propriétés et les champs de votre DTO.
J'ai eu ce même problème, où mon DTO était devenu nul. J'ai trouvé que la raison était qu'une des propriétés pointait vers un objet qui ne peut pas être sérialisé :( ce qui empêche le formateur de média d'analyser les données. Ainsi, l'objet était toujours nul. J'espère qu'il aide les autres aussi
la source
Vérifiez vos types de données. Le classeur de modèle dotnet ne convertira pas un flottant en un entier (et je suppose que d'autres concepts connexes). Cela entraînera le rejet de l'ensemble du modèle.
Si vous avez json comme ceci:
mais votre modèle c # ressemble à ceci:
le classeur de modèle rejettera le modèle et vous obtiendrez nul.
la source
Je suis assez tard pour cela, mais je rencontrais des problèmes similaires et après une journée passée à parcourir de nombreuses réponses ici et à obtenir des informations de base, j'ai trouvé la solution la plus simple / légère pour renvoyer un ou plusieurs paramètres à une action Web API 2. suit:
Cela suppose que vous savez comment configurer un contrôleur / une action d'API Web avec un routage correct, sinon reportez-vous à: https://docs.microsoft.com/en-us/aspnet/web-api/overview/getting-started-with -aspnet-web-api / tutorial-your-first-web-api .
Tout d'abord l'action du contrôleur, cette solution nécessite également la bibliothèque Newtonsoft.Json.
Côté client à l'aide de jQuery
Le problème clé que j'ai trouvé était de vous assurer de ne renvoyer qu'un seul paramètre global à l'API Web et de vous assurer qu'il n'a pas de nom juste la valeur
{ '': dataToSend }
sinon votre valeur sera nulle côté serveur.Avec cela, vous pouvez envoyer un ou plusieurs paramètres à l'API Web dans une structure JSON et vous n'avez pas besoin de déclarer des objets supplémentaires côté serveur pour gérer des données complexes. Le JObject vous permet également d'itérer dynamiquement tous les paramètres transmis afin de faciliter l'évolutivité si vos paramètres changent au fil du temps. Espérons que cela aide quelqu'un qui se débattait comme moi.
la source
Le passage correct d'un seul paramètre dans le corps à WebAPI fonctionne ce code
$.post(url, { '': productId }
Et l'attraper en action
[HttpPost] public ShoppingCartAddRemoveViewModel Delete([FromBody]string value)
La clé est d'utiliser le mot magique «valeur». Il peut également s'agir d'un entier ou d'un type primitif. Peu importe le type de contenu ou les corrections d'en-tête, Mess est que ce code ne fonctionne pas dans l'action post mvc.
la source