Pregunta

Cuando intento puedan enviar a la dirección URL que se traduce en la siguiente excepción:

  

El servidor remoto devolvió un error:   (417) Expectativa Failed.

Aquí hay un código de ejemplo:

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.

El uso de un par HttpWebRequest/HttpWebResponse o un HttpClient no hacer una diferencia.

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

¿Fue útil?

Solución

System.NET.HttpWebRequest añade la cabecera 'cabecera HTTP 'Hay que esperar: 100-continuar'' a cada solicitud a menos que pedir explícitamente que no utilizará estableciendo este propiedad estática en false:

System.Net.ServicePointManager.Expect100Continue = false;

Algunos servidores ahogan en esa cabecera y envía de vuelta el error 417 que se está viendo.

deis un tiro.

Otros consejos

Otra forma -

Añadir estas líneas a su archivo de configuración sección de configuración de la aplicación:

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

Esta misma situación y error también pueden surgir con un jabón proxy de servicio web predeterminado generado asistente (no 100% si este es también el caso en la pila System.ServiceModel WCF) cuando en tiempo de ejecución:

  • la máquina del usuario final está configurado (en los ajustes de Internet) para usar un proxy que no entiende HTTP 1.1
  • el cliente termina el envío de algo que un proxy HTTP 1.0 duerma entender (comúnmente una cabecera Expect como parte de un POST HTTP o solicitud PUT debido a una convención protocolo estándar de enviar la solicitud en dos partes como cubiertos en las observaciones aquí )

... produciendo un 417.

Como se trata en las otras respuestas, si la cuestión específica se encuentra con es que la cabecera Expect está causando el problema, entonces ese problema específico puede ser encaminado en torno al hacer un cambio relativamente mundial fuera de la de dos partes PUT / POST transmisión a través de System.Net.ServicePointManager.Expect100Continue .

Sin embargo esto no soluciona el problema subyacente completa - la pila pueda estar utilizando HTTP 1.1 cosas específicas, tales como KeepAlive etc. (. Aunque en muchos casos las otras respuestas cubren los casos principales)

El problema actual, sin embargo es que el código autogenerado asume que está bien para ir a ciegas utilizando HTTP 1.1 facilidades que todo el mundo entiende esto. Para detener esta suposición de un proxy de servicio web específica, se puede cambiar reemplazar el valor predeterminado subyacente HttpWebRequest.ProtocolVersion del valor predeterminado de 1,1 mediante la creación de una clase de proxy derivada que anula 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 el asistente Agregar referencia Web escupió a la vista.)


ACTUALIZACIÓN: He aquí un impl estoy usando en la 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 };
    }
}

¿El formulario al que intenta emular tiene dos campos, usuario y contraseña?

Si es así, esta línea:

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

no es correcta.

usted necesitaría dos líneas como:

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

Editar:

De acuerdo, ya que no es el problema, una forma de hacer frente a esto es utilizar algo como violinista o Wireshark para ver lo que está siendo enviada al servidor web desde el navegador con éxito, luego compararlo con lo que se envía desde su código. Si usted va a un puerto normal de 80 de .Net, violinista seguirá capturar este tráfico.

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

Solución de un lado proxy, que se enfrentan algunos problemas en el proceso de establecimiento de conexión SSL y tuve que forzar mi servidor proxy para enviar solicitudes a través de HTTP / 1.0 para resolver el problema mediante el establecimiento de este argumento en el SetEnv force-proxy-request-1.0 1 httpd.conf SetEnv proxy-nokeepalive 1 después de que me enfrentaba el error 417 como mi aplicación cliente estaba usando HTTP / 1.1 y el proxy se vio obligado a utilizar HTTP / 1.0, el problema se resolvió mediante el establecimiento de este parámetro en el httpd.conf en el RequestHeader unset Expect early lado del proxy sin necesidad de cambiar nada en el lado del cliente, espero que esta ayuda.

Para Powershell es

[System.Net.ServicePointManager]::Expect100Continue = $false

Si está utilizando " HttpClient ", y usted no desea utilizar configuración global que afecta todo lo que programa que puede utilizar:

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

Me está utilizando " cliente Web " Creo que se puede tratar de eliminar esta cabecera llamando a:

 var client = new WebClient();
 client.Headers.Remove(HttpRequestHeader.Expect);

En mi situación, este error parece ocurrir sólo si el ordenador de mi cliente tiene una estricta política de cortafuegos, que impide que mi programa de comunicación con el servicio web.

Así única solución que pude encontrar es atrapar el error e informar a los usuarios acerca de cómo cambiar la configuración del cortafuegos de forma manual.

El enfoque web.config trabaja para los servicios de formulario de InfoPath llamadas a servicios web reglas habilitadas IntApp.

  <system.net>
    <defaultProxy />
    <settings> <!-- 20130323 bchauvin -->
        <servicePointManager expect100Continue="false" />
    </settings>
  </system.net>
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top