Ця ж ситуація та помилка також можуть виникнути, коли майстер за промовчанням створив проксі-сервер веб-сервісу SOAP (не 100%, якщо це також має місце на System.ServiceModel
стеку WCF ) під час виконання:
- машина кінцевого користувача налаштована (у налаштуваннях Інтернету) для використання проксі-сервера, який не розуміє 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 , створивши похідний клас проксі, який перевизначає, як показано в цій публікації : -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 };
}
}