J'essaie d'utiliser un HttpClient
pour un service tiers qui nécessite une authentification HTTP de base. J'utilise le AuthenticationHeaderValue
. Voici ce que j'ai trouvé jusqu'à présent:
HttpRequestMessage<RequestType> request =
new HttpRequestMessage<RequestType>(
new RequestType("third-party-vendor-action"),
MediaTypeHeaderValue.Parse("application/xml"));
request.Headers.Authorization = new AuthenticationHeaderValue(
"Basic", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(
string.Format("{0}:{1}", "username", "password"))));
var task = client.PostAsync(Uri, request.Content);
ResponseType response = task.ContinueWith(
t =>
{
return t.Result.Content.ReadAsAsync<ResponseType>();
}).Unwrap().Result;
Il semble que l'action POST fonctionne bien, mais je ne récupère pas les données que j'attends. Grâce à des essais et des erreurs, et finalement à l'aide de Fiddler pour flairer le trafic brut, j'ai découvert l'autorisation l'en-tête n'est pas envoyé.
J'ai vu this , mais je pense avoir le schéma d'authentification spécifié dans le cadre du constructeur AuthenticationHeaderValue
.
Y a-t-il quelque chose que j'ai manqué?
Votre code semble qu'il devrait fonctionner - je me souviens avoir rencontré un problème similaire en définissant les en-têtes d'autorisation et résolu en faisant un Headers.Add () au lieu de le définir:
request.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:{1}", "username", "password"))));
PDATE: Cela ressemble à lorsque vous faites une requête. Contenu, tous les en-têtes ne sont pas reflétés dans l'objet de contenu. Vous pouvez le voir en inspectant request.Headers vs request.Content.Headers. Une chose que vous voudrez peut-être essayer est d'utiliser SendAsync au lieu de PostAsync. Par exemple:
HttpRequestMessage<RequestType> request =
new HttpRequestMessage<RequestType>(
new RequestType("third-party-vendor-action"),
MediaTypeHeaderValue.Parse("application/xml"));
request.Headers.Authorization =
new AuthenticationHeaderValue(
"Basic",
Convert.ToBase64String(
System.Text.ASCIIEncoding.ASCII.GetBytes(
string.Format("{0}:{1}", "username", "password"))));
request.Method = HttpMethod.Post;
request.RequestUri = Uri;
var task = client.SendAsync(request);
ResponseType response = task.ContinueWith(
t =>
{ return t.Result.Content.ReadAsAsync<ResponseType>(); })
.Unwrap().Result;
Cela fonctionnerait également et vous n'auriez pas à gérer les conversions de chaînes en base64:
var handler = new HttpClientHandler();
handler.Credentials = new System.Net.NetworkCredential("username", "password");
var client = new HttpClient(handler);
...
Essayez de définir l'en-tête sur le client:
DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes(String.Format("{0}:{1}", userName, password))));
Cela fonctionne pour moi.
En fait, votre problème est avec PostAsync
- vous devez utiliser SendAsync
. Dans votre code - client.PostAsync(Uri, request.Content);
envoie uniquement le contenu, les en-têtes de message de demande ne sont pas inclus. La bonne façon est:
HttpRequestMessage message = new HttpRequestMessage(HttpMethod.Post, url)
{
Content = content
};
message.Headers.Authorization = new AuthenticationHeaderValue("Basic", credentials);
httpClient.SendAsync(message);