System.ServiceModel
在运行时,默认的向导生成的SOAP Web服务代理(如果在WCF 堆栈中也是如此,则不是100%)也会产生这种相同的情况和错误:
- 最终用户计算机(在“ Internet设置”中)配置为使用不理解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设施盲目地进行,因为每个人都理解这一点。为了制止这种假设为特定的Web服务代理,可以改变覆盖默认的基本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
“添加Web参考”向导出现在您的代理那里。)
更新:这是我在生产中使用的暗示:
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 };
}
}