HTTP POST renvoie L'erreur: 417 " L'attente a échoué."

Lorsque j'essaie de poster sur une URL, il en résulte l'exception suivante:

Le serveur distant a renvoyé une erreur: (417) L'Attente A Échoué.

Voici un exemple de code:

var client = new WebClient();

var postData = new NameValueCollection();
postData.Add("postParamName", "postParamValue");

byte[] responseBytes = client.UploadValues("http://...", postData);
string response = Encoding.UTF8.GetString(responseBytes); // (417) Expectation Failed.

L'utilisation d'une paire HttpWebRequest/HttpWebResponse ou d'un HttpClient ne fait aucune différence.

Qu'est-ce qui cause cette exception?

203
demandé sur Saeb Amini 2009-02-19 20:57:16

9 réponses

System. Net. HttpWebRequest ajoute l'en-tête 'HTTP header" Expect: 100-Continue" ' à chaque requête sauf si vous le demandez explicitement en définissant Cette propriété statique à false:

System.Net.ServicePointManager.Expect100Continue = false;

Certains serveurs s'étouffent sur cet en-tête et renvoient l'erreur 417 que vous voyez.

Donner un coup de feu.

456
répondu xcud 2009-02-19 19:45:45

Une autre façon -

Ajoutez ces lignes à la section de configuration du fichier de configuration de votre application:

<system.net>
    <settings>
        <servicePointManager expect100Continue="false" />
    </settings>
</system.net>
112
répondu Engin Ardıç 2016-08-06 12:10:22

Cette même situation et cette erreur peuvent également survenir avec un proxy de service Web SOAP généré par l'assistant par défaut (pas à 100% Si c'est également le cas sur la pile WCF System.ServiceModel) lors de l'exécution:

  • la machine de l'utilisateur final est configurée (dans les paramètres Internet) pour utiliser un proxy qui ne comprend PAS HTTP 1.1
  • le client finit par envoyer quelque chose qu'un proxy HTTP 1.0 ne comprend pas (généralement un en-tête Expect dans le cadre D'une requête HTTP POST ou PUT en raison d'un protocole standard convention d'envoi de la demande en deux parties comme couvert dans les remarques ici )

... donnant un 417.

Comme couvert dans les autres réponses, si le problème spécifique que vous rencontrez est que l'en-tête Expect cause le problème, alors ce problème spécifique peut être acheminé en désactivant relativement globalement la transmission PUT/POST en deux parties via System.Net.ServicePointManager.Expect100Continue.

Cependant, cela ne résout pas le problème sous-jacent complet-le stack peut toujours utiliser des choses spécifiques à HTTP 1.1 telles que KeepAlives, etc. (bien que dans de nombreux cas, les autres réponses couvrent les cas principaux.)

Le problème réel est cependant que le code généré automatiquement suppose qu'il est correct d'utiliser aveuglément les installations HTTP 1.1 car tout le monde le comprend. Pour arrêter cette hypothèse pour un proxy de service Web spécifique, on peut changer remplacer le sous-jacent par défautHttpWebRequest.ProtocolVersion de la valeur par défaut de 1.1 en créant un Proxy dérivé classe qui remplace protected override WebRequest GetWebRequest(Uri uri) comme indiqué dans ce post:-

public class MyNotAssumingHttp11ProxiesAndServersProxy : MyWS
{
    protected override WebRequest GetWebRequest(Uri uri)
    {
      HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(uri);
      request.ProtocolVersion = HttpVersion.Version10;
      return request;
    }
}

(où MyWS est le proxy que L'Assistant D'ajout de référence Web vous a craché.)


UPDATE: voici un impl que j'utilise en production:

class ProxyFriendlyXXXWs : BasicHttpBinding_IXXX
{
    public ProxyFriendlyXXXWs( Uri destination )
    {
        Url = destination.ToString();
        this.IfProxiedUrlAddProxyOverriddenWithDefaultCredentials();
    }

    // Make it squirm through proxies that don't understand (or are misconfigured) to only understand HTTP 1.0 without yielding HTTP 417s
    protected override WebRequest GetWebRequest( Uri uri )
    {
        var request = (HttpWebRequest)base.GetWebRequest( uri );
        request.ProtocolVersion = HttpVersion.Version10;
        return request;
    }
}

static class SoapHttpClientProtocolRealWorldProxyTraversalExtensions
{
    // OOTB, .NET 1-4 do not submit credentials to proxies.
    // This avoids having to document how to 'just override a setting on your default proxy in your app.config' (or machine.config!)
    public static void IfProxiedUrlAddProxyOverriddenWithDefaultCredentials( this SoapHttpClientProtocol that )
    {
        Uri destination = new Uri( that.Url );
        Uri proxiedAddress = WebRequest.DefaultWebProxy.GetProxy( destination );
        if ( !destination.Equals( proxiedAddress ) )
            that.Proxy = new WebProxy( proxiedAddress ) { UseDefaultCredentials = true };
    }
}
30
répondu Ruben Bartelink 2013-05-03 09:37:28

Le formulaire que vous essayez d'émuler a-t-il deux champs, Nom d'utilisateur et mot de passe?

Si oui, cette ligne:

 postData.Add("username", "password");

N'est pas correct.

Vous auriez besoin de deux lignes comme:

 postData.Add("username", "Moose");
postData.Add("password", "NotMoosespasswordreally");

Modifier:

D'accord, puisque ce n'est pas le problème, une façon de résoudre ce problème est d'utiliser quelque chose comme Fiddler ou Wireshark pour regarder ce qui est envoyé au serveur web à partir du navigateur avec succès, puis comparez cela à ce qui est envoyé à partir de votre code. Si vous allez à une normale port 80 de. Net, Fiddler va toujours capturer ce trafic.

Il y a probablement un autre champ caché sur le formulaire que le serveur web attend que vous n'envoyez pas.

5
répondu Moose 2009-02-19 19:39:01

Solution du côté du proxy, j'ai rencontré quelques problèmes dans le processus de handshake SSL et j'ai dû forcer mon serveur proxy à envoyer des requêtes en utilisant HTTP / 1.0 Pour résoudre le problème en définissant cet argument dans le httpd.conf SetEnv force-proxy-request-1.0 1 SetEnv proxy-nokeepalive 1 Après cela, j'ai fait face à l'erreur 417 car l'application de mes clients utilisait HTTP/1.1 et le proxy a été forcé D'utiliser HTTP/1.0, le problème a été résolu en définissant ce paramètre dans le httpd.conf du côté proxy RequestHeader unset Expect early sans avoir besoin de changer quoi que ce soit du côté client, espérons cela aide.

3
répondu Hytham 2013-05-28 06:19:22

Si vous utilisez " HttpClient ", et que vous ne souhaitez pas utiliser la configuration globale pour affecter tout ce que vous pouvez utiliser:

 HttpClientHandler httpClientHandler = new HttpClientHandler();
 httpClient.DefaultRequestHeaders.ExpectContinue = false;

I vous utilisez " WebClient " je pense que vous pouvez essayer de supprimer cet en-tête en appelant:

 var client = new WebClient();
 client.Headers.Remove(HttpRequestHeader.Expect);
1
répondu Aviram Fireberger 2017-07-11 12:45:17

Pour Powershell c'est

[System.Net.ServicePointManager]::Expect100Continue = $false
1
répondu TNT 2018-03-01 18:03:50

Le web.l'approche config fonctionne pour les appels InfoPath form services aux règles activées par le service Web IntApp.

  <system.net>
    <defaultProxy />
    <settings> <!-- 20130323 bchauvin -->
        <servicePointManager expect100Continue="false" />
    </settings>
  </system.net>
0
répondu BobC 2013-03-24 22:58:47

Dans Ma situation, cette erreur semble se produire uniquement si l'ordinateur de mon client a une politique de pare-feu stricte, ce qui empêche mon programme de communiquer avec le service web.

Donc, la seule solution que j'ai pu trouver est d'attraper l'erreur et d'informer l'utilisateur de la modification manuelle des paramètres du pare-feu.

0
répondu Emre Can Serteli 2015-07-21 07:51:39