Та же самая ситуация и ошибка могут также возникнуть с мастером по умолчанию, сгенерированным прокси-сервером веб-службы SOAP (не 100%, если это также имеет место в WCF). System.ServiceModel
стеке ), когда во время выполнения:
- компьютер конечного пользователя настроен (в настройках Интернета) на использование прокси, который не понимает HTTP 1.1
- клиент заканчивает тем, что отправляет что-то, чего не понимает прокси HTTP 1.0 (обычно
Expect
заголовок как часть HTTP POST
или PUT
запроса из-за стандартного протокола протокола отправки запроса в двух частях, как описано в примечаниях здесь )
... получая 417.
Как описано в других ответах, если конкретная проблема, с которой вы сталкиваетесь, заключается в том, что Expect
заголовок вызывает проблему, то эту конкретную проблему можно обойти, выполнив относительно глобальное отключение двухчастной передачи PUT / POST черезSystem.Net.ServicePointManager.Expect100Continue
.
Однако это не решает основную проблему - стек все еще может использовать специфичные для HTTP 1.1 вещи, такие как KeepAlives и т. Д. (Хотя во многих случаях другие ответы охватывают основные случаи).
Однако реальная проблема заключается в том, что автоматически сгенерированный код предполагает, что можно использовать вслепую, используя средства HTTP 1.1, поскольку все это понимают. Чтобы прекратить это предположение для определенного прокси-сервера веб-службы, можно изменить переопределение значения HttpWebRequest.ProtocolVersion
по умолчанию на значение по умолчанию для 1.1, путем создания производного класса Proxy, который переопределяет, как показано в этом посте : -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;
}
}
(где MyWS
находится прокси, над которым выпал мастер добавления веб-ссылок?)
ОБНОВЛЕНИЕ: Вот что я использую в производстве:
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 };
}
}