158 votos

HTTP POST devuelve el Error: 417 "expectativa falló." (C#)

Estoy tratando de acceder a un sitio web mediante HTTP POST. Estoy seguro de que el sitio web sólo requiere de dos POST campos: nombre de usuario y contraseña; no hay campos ocultos.

Sigo recibiendo la siguiente excepción cuando trato de leer la respuesta:

"El servidor remoto devolvió un error: (417) Expectativa De Error".

He intentado tanto HTTPWebResponse/HttpWebRequest y WebClient.

He aquí un ejemplo del código que estoy usando:

WebClient client = new WebClient();

NameValueCollection postData = new NameValueCollection();
postData.Add("username", "myUserName");
postData.Add("password", "myPassword");

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

Cuál es la causa de esta excepción?

360voto

xcud Puntos 6878

System.Net.HttpWebRequest agrega el encabezado ' encabezado HTTP "espera: 100-continuar"' a cada solicitud a menos que explícitamente si le pides no estableciendo esta propiedad estática en false:

System.Net.ServicePointManager.Expect100Continue = false;

Algunos servidores estrangulación de esa cabecera y envían atrás los 417 error que estás viendo.

Darle una oportunidad.

82voto

Engin Ardıç Puntos 1447

Otro, añada esta líneas a la sección de configuración aplicación config file;

<system.net>
    <settings>
        <servicePointManager expect100Continue="false" />
    </settings>
</system.net>

22voto

Ruben Bartelink Puntos 23945

Esta misma situación y error también puede surgir de manera predeterminada con una asistente generado JABÓN proxy de Servicio Web (no al 100% si este es también el caso en el WCF System.ServiceModel de pila) cuando en tiempo de ejecución:

  • el usuario final de la máquina está configurada (en la Configuración de Internet) el uso de un proxy que no entiende de HTTP 1.1
  • el cliente termina de enviar algo que un 1.0 de HTTP proxy no entiende (comúnmente un Expect de encabezado como parte de un HTTP POST o PUT solicitud debido a un estándar de protocolo de la convención de envío de la petición en dos partes como se explica en los Comentarios de aquí)

... produciendo un 417.

Como se explica en las otras respuestas, si el problema específico es que el Expect de encabezado está causando el problema, entonces que problema específico puede ser enrutados a su alrededor haciendo un relativamente mundial de la desconexión de los dos-parte/POSTERIORES a la transmisión a través de System.Net.ServicePointManager.Expect100Continue.

Sin embargo, esto no soluciona la completa problema de fondo - la pila todavía puede ser usar HTTP 1.1 cosas específicas tales como conexiones abiertas, etc. (aunque en muchos casos las respuestas de cubrir el principal de los casos).

El problema real es, sin embargo, que el código generado automáticamente asume que es ACEPTAR a ciegas con HTTP 1.1 instalaciones como todo el mundo lo entiende. Para detener esta hipótesis específica a un proxy de Servicio Web, uno puede cambiar reemplazar el defecto subyacente HttpWebRequest.ProtocolVersion desde el valor predeterminado de 1.1 por la creación de un derivado de la clase Proxy que invalida protected override WebRequest GetWebRequest(Uri uri) como se muestra en este post:-

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

(donde MyWS es el proxy Agregar Referencia Web asistente para escupió a usted.)


ACTUALIZACIÓN: he Aquí un impl estoy usando en producción:

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 };
    }
}

6voto

Jon Skeet Puntos 692016

Que actualmente estás posteando "username" como una llave y la "contraseña" como el valor. Cómo

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

?

5voto

Moose Puntos 3792

¿La forma que está tratando de emular tiene dos campos, nombre de usuario y contraseña?

Si es así, esta línea:

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

no es correcto.

necesitaría dos líneas como:

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

Edición:

Bien, ya que ese no es el problema, una forma de abordar esto es usar algo como Violinista o Wireshark para ver lo que se envía al servidor web desde el navegador con éxito, a continuación, compare eso con lo que se envían desde el código. Si usted va a un puerto estándar 80 de .Net, el Violinista seguirá la captura de este tráfico.

Probablemente hay algún otro campo oculto en el formulario que el servidor web está a la espera de que usted no está enviando.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X