A mesma situação e erro também podem surgir com um proxy de serviço da Web SOAP gerado por um assistente padrão (não 100% se esse também for o caso na System.ServiceModel
pilha do WCF ) quando em tempo de execução:
- a máquina do usuário final está configurada (nas Configurações da Internet) para usar um proxy que não entende o HTTP 1.1
- o cliente acaba enviando algo que um proxy HTTP 1.0 não entende (geralmente um
Expect
cabeçalho como parte de um HTTP POST
ou PUT
solicitação devido a uma convenção de protocolo padrão de enviar a solicitação em duas partes, conforme coberto nas observações aqui )
... produzindo um 417.
Conforme abordado nas outras respostas, se o problema específico em que você se deparar for o fato de o Expect
cabeçalho estar causando o problema, esse problema específico poderá ser roteado ao se fazer uma desativação relativamente global da transmissão PUT / POST em duas partes System.Net.ServicePointManager.Expect100Continue
.
No entanto, isso não resolve o problema subjacente completo - a pilha ainda pode estar usando coisas específicas do HTTP 1.1, como KeepAlives etc. (embora em muitos casos as outras respostas abranjam os casos principais).
O problema real é, no entanto, que o código gerado automaticamente assume que não há problema em usar cegamente os recursos do HTTP 1.1, pois todos entendem isso. Para interromper essa suposição para um proxy de serviço da Web específico, é possível alterar a substituição do padrão subjacente HttpWebRequest.ProtocolVersion
do padrão de 1.1 , criando uma classe de proxy derivada que substitui como mostrado nesta postagem : -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;
}
}
(onde MyWS
está o proxy que o assistente Adicionar Referência da Web cuspiu em você.)
UPDATE: Aqui está um impl estou usando na produção:
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 };
}
}