สถานการณ์และข้อผิดพลาดเดียวกันนี้ยังสามารถเกิดขึ้นได้ด้วยตัวช่วยสร้างเริ่มต้นที่สร้างพร็อกซี SOAP Web Service (ไม่ใช่ 100% หากเป็นกรณีนี้ในSystem.ServiceModel
สแต็กWCF ) เมื่อรันไทม์:
- มีการกำหนดค่าเครื่องผู้ใช้ปลายทาง (ในการตั้งค่าอินเทอร์เน็ต) เพื่อใช้พรอกซีที่ไม่เข้าใจ HTTP 1.1
- ไคลเอ็นต์สิ้นสุดการส่งสิ่งที่พร็อกซี HTTP 1.0 ไม่เข้าใจ (โดยทั่วไป
Expect
ส่วนหัวเป็นส่วนหนึ่งของ HTTP POST
หรือการPUT
ร้องขอเนื่องจากการประชุมโปรโตคอลมาตรฐานในการส่งคำขอเป็นสองส่วนตามที่กล่าวไว้ในหมายเหตุที่นี่ )
... ยอมแพ้ 417
ในฐานะที่เป็นที่กล่าวถึงในคำตอบอื่น ๆ ถ้าปัญหาเฉพาะที่คุณใช้เป็นก็คือExpect
ส่วนหัวที่เป็นสาเหตุของปัญหาแล้วว่าปัญหาที่เฉพาะเจาะจงสามารถส่งไปรอบ ๆ ด้วยการทำสวิตชิ่งค่อนข้างทั่วโลกออกจาก PUT สองส่วน / 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
พร็อกซีตัวช่วยสร้างเพิ่มการอ้างอิงเว็บอยู่ที่คุณ)
UPDATE: นี่คือนัยที่ฉันใช้ในการผลิต:
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 };
}
}