Esta misma situación y error también pueden surgir con un proxy de servicio web SOAP generado por asistente predeterminado (no 100% si este es también el caso en la System.ServiceModel
pila de WCF ) cuando está en tiempo de ejecución:
- la máquina del usuario final está configurada (en la Configuración de Internet) para usar un proxy que no comprende HTTP 1.1
- el cliente termina enviando algo que un proxy HTTP 1.0 no comprende (comúnmente un
Expect
encabezado como parte de un HTTP POST
o PUT
solicitud debido a una convención de protocolo estándar de enviar la solicitud en dos partes como se cubre en los Comentarios aquí )
... produciendo un 417.
Como se explica en las otras respuestas, si el problema específico con el que se encuentra es que el Expect
encabezado está causando el problema, entonces ese problema específico se puede enrutar haciendo una desconexión relativamente global de la transmisión PUT / POST de dos partes a través de System.Net.ServicePointManager.Expect100Continue
.
Sin embargo, esto no soluciona el problema subyacente completo: la pila aún puede estar usando cosas específicas de HTTP 1.1 como KeepAlives, etc. (aunque en muchos casos las otras respuestas cubren los casos principales).
Sin embargo, el problema real es que el código autogenerado supone que está bien usar ciegamente las funciones de HTTP 1.1, ya que todos entienden esto. Para detener esta suposición para un proxy de servicio web específico, uno puede cambiar anular el valor subyacente HttpWebRequest.ProtocolVersion
predeterminado del valor predeterminado de 1.1 creando una clase de proxy derivada que se anula como se muestra en esta publicación :protected override WebRequest GetWebRequest(Uri uri)
public class MyNotAssumingHttp11ProxiesAndServersProxy : MyWS
{
protected override WebRequest GetWebRequest(Uri uri)
{
HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(uri);
request.ProtocolVersion = HttpVersion.Version10;
return request;
}
}
(¿dónde MyWS
está el proxy que el asistente para agregar referencias web le escuchó?)
ACTUALIZACIÓN: Aquí hay un impl que 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 };
}
}