J'essaie de définir l'en- Content-Type
tête d'un HttpClient
objet comme requis par une API que j'appelle.
J'ai essayé de définir Content-Type
comme ci-dessous:
using (var httpClient = new HttpClient())
{
httpClient.BaseAddress = new Uri("http://example.com/");
httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
httpClient.DefaultRequestHeaders.Add("Content-Type", "application/json");
// ...
}
Cela me permet d'ajouter l'en- Accept
tête mais lorsque j'essaye de l'ajouter, Content-Type
il lance l'exception suivante:
Nom d'en-tête mal utilisé. Assurez-vous que les en-têtes de demande sont utilisés avec
HttpRequestMessage
, les en-têtes de réponse avecHttpResponseMessage
et les en-têtes de contenu avec lesHttpContent
objets.
Comment puis-je définir l'en- Content-Type
tête dans une HttpClient
demande?
Réponses:
Le type de contenu est un en-tête du contenu, pas de la demande, c'est pourquoi cela échoue.
AddWithoutValidation
comme suggéré par Robert Levy peut fonctionner, mais vous pouvez également définir le type de contenu lors de la création du contenu de la demande lui-même (notez que l'extrait de code ajoute "application / json" à deux endroits - pour les en-têtes Accept et Content-Type):la source
Response.Content.Headers
fonctionnera la plupart du temps.Response.Content.Headers
pour l'API Web ASP.Net n'ont pas fonctionné non plus, mais vous pouvez facilement le configurer en utilisantHttpContext.Current.Response.ContentType
si vous en avez besoin.Pour ceux qui n'ont pas vu le commentaire de Johns sur la solution carlos ...
la source
response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/xml; charset=utf-8");
Si cela ne vous dérange pas une petite dépendance de bibliothèque, Flurl.Http [divulgation: je suis l'auteur] rend cela ultra simple. Sa
PostJsonAsync
méthode prend en charge à la fois la sérialisation du contenu et la définition de l'en-content-type
tête, etReceiveJson
désérialise la réponse. Si l'en-accept
tête est requis, vous devrez le définir vous-même, mais Flurl fournit également un moyen assez propre de le faire:Flurl utilise HttpClient et Json.NET sous le capot, et c'est un PCL, donc cela fonctionnera sur une variété de plates-formes.
la source
essayez d'utiliser TryAddWithoutValidation
la source
Misused header name
erreur est confirmée avec dotnet core 2.2. J'ai dû utiliser la réponse stackoverflow.com/a/10679340/2084315 de @ carlosfigueira ..Net essaie de vous forcer à obéir à certaines normes, à savoir que l' en-
Content-Type
tête ne peut être spécifié sur les demandes qui ont un contenu (par exemplePOST
,PUT
etc.). Par conséquent, comme d'autres l'ont indiqué, la meilleure façon de définir l'en-Content-Type
tête consiste à utiliser laHttpContent.Headers.ContentType
propriété.Cela dit, certaines API (telles que l' API LiquidFiles , à partir du 2016-12-19) nécessitent de définir l'en-
Content-Type
tête d'uneGET
demande. .Net ne permettra pas de définir cet en-tête sur la demande elle-même - même en utilisantTryAddWithoutValidation
. De plus, vous ne pouvez pas spécifier unContent
pour la demande - même s'il est de longueur nulle. La seule façon dont je pouvais sembler contourner cela était de recourir à la réflexion. Le code (au cas où quelqu'un d'autre en aurait besoin) estÉditer:
Comme indiqué dans les commentaires, ce champ a des noms différents dans différentes versions de la DLL. Dans le code source sur GitHub , le champ est actuellement nommé
s_invalidHeaders
. L'exemple a été modifié pour tenir compte de cela selon la suggestion de @David Thompson.la source
Quelques informations supplémentaires sur .NET Core (après avoir lu le post d'erdomke sur la définition d'un champ privé pour fournir le type de contenu sur une demande qui n'a pas de contenu) ...
Après avoir débogué mon code, je ne vois pas le champ privé à définir via la réflexion - j'ai donc pensé essayer de recréer le problème.
J'ai essayé le code suivant en utilisant .Net 4.6:
Et, comme prévu, j'obtiens une exception globale avec le contenu
"Cannot send a content-body with this verb-type."
Cependant, si je fais la même chose avec .NET Core (1.1) - je n'ai pas d'exception.Ma demande a été très heureusement répondu par mon application serveur, et le type de contenu a été repris.
J'en ai été agréablement surpris et j'espère que cela aide quelqu'un!
la source
Appelez
AddWithoutValidation
au lieu deAdd
(voir ce lien MSDN ).Alternativement, je suppose que l'API que vous utilisez ne l'exige vraiment que pour les requêtes POST ou PUT (pas les requêtes GET ordinaires). Dans ce cas, lorsque vous appelez
HttpClient.PostAsync
et transmettez unHttpContent
, définissez-le sur laHeaders
propriété de cetHttpContent
objet.la source
Pour ceux qui ont des problèmes avec
charset
J'ai eu un cas très spécial que le fournisseur de services n'a pas accepté charset, et ils refusent de changer la sous-structure pour le permettre ... Malheureusement, HttpClient définissait automatiquement l'en-tête via StringContent, et peu importe si vous passez null ou Encoding.UTF8, il définira toujours le jeu de caractères ...
Aujourd'hui, j'étais sur le point de changer le sous-système; passer de HttpClient à autre chose, que quelque chose m'est venu à l'esprit ..., pourquoi ne pas utiliser la réflexion pour vider le "charset"? ... Et avant même de l'essayer, j'ai pensé à un moyen, "peut-être que je peux le changer après l'initialisation", et cela a fonctionné.
Voici comment définir l'en-tête "application / json" exact sans "; charset = utf-8".
Remarque: La
null
valeur de ce qui suit ne fonctionnera pas et ajoutera "; charset = utf-8"ÉDITER
@DesertFoxAZ suggère que le code suivant peut également être utilisé et fonctionne correctement. (je ne l'ai pas testé moi-même)
la source
C'est tout ce dont vous avez besoin.
En utilisant Newtonsoft.Json, si vous avez besoin d'un contenu en tant que chaîne json.
la source
HttpMessageHandler handler = new WebRequestHandler(); HttpResponseMessage result; using (var client = (new HttpClient(handler, true))) { result = client.PostAsync(fullUri, content).Result; }
Ok, ce n'est pas HTTPClient mais si vous pouvez l'utiliser, WebClient est assez simple:
la source
Vous pouvez l'utiliser, ce sera du travail!
la source
Je le trouve le plus simple et le plus facile à comprendre de la manière suivante:
la source
Vous devez le faire comme ceci:
la source