简体   繁体   English

正确处理期望失败(417),并在WCF客户端应用程序中更改Expect100Continue

[英]Correcty handle Expectation failed (417) and change Expect100Continue in WCF client app

My application is a C# Windows service that consumes a WCF service. 我的应用程序是使用WCF服务的C#Windows服务。 When the first "Expectation failed (417)" error occurs, I change both ServicePointManager.Expect100Continue and ServicePoint.Expect100Continue to false : 当出现第一个“预期失败(417)”错误时,我将ServicePointManager.Expect100ContinueServicePoint.Expect100Continue都更改为false

try
{
    //ServicePointManager.Expect100Continue = false; // If uncomment all work
    var svc = new ServiceClient();
    svc.GetData(); // first error
}
catch (ProtocolException pex)
{
    if (pex.Message.Contains("(417)"))
    {
        ServicePointManager.Expect100Continue = false;
        var sp = ServicePointManager.FindServicePoint(new Uri(@"http://addr.to.service/service.svc"));
        sp.Expect100Continue = false;

        var svc = new ServiceClient();
        svc.GetData(); // second same error
    }
}

However, the second call to the service also fails. 但是,第二次调用该服务也失败。 But if I set Expect100Continue to false before any connection, communication with the service works correctly. 但是,如果在进行任何连接之前将Expect100Continue设置为false ,则与该服务的通信将正常进行。

Is this way correctly to handle Expect100Continue errors? 这样正确地处理Expect100Continue错误吗? I need the application adapts automatically without user action. 我需要应用程序自动适应而无需用户干预。 What am I forgetting to do this work? 我忘了做这项工作是什么?

Most of the settings on ServicePointManager are treated as the default values applied on all NEW ServicePoints that are created after that point in the application's life. ServicePointManager上的大多数设置都被视为应用到应用程序生命周期中在该点之后创建的所有新ServicePoints上应用的默认值。 In the case where you change the setting after seeing the error, you are not actually changing anything on existing ServicePoint instances, including the instance associated with the connection used by WCF in this case. 在看到错误后更改设置的情况下,实际上并没有更改现有ServicePoint实例上的任何内容,包括与WCF在这种情况下使用的连接关联的实例。

In your Sample code you are calling ServicePointManager.FindServicePoint to try to find the correct ServicePoint. 在示例代码中,您正在调用ServicePointManager.FindServicePoint以尝试找到正确的ServicePoint。 However, FindServicePoint has several overloads and it is easy to use that API incorrectly. 但是, FindServicePoint具有多个重载,并且很容易错误地使用该API。 For instance, FindServicePoint will try to take into account things http/https, the host you are connecting to, your proxy configuration, etc. If you are not providing the correct parameters to FindServicePoint , you can easily end up getting the wrong ServicePoint returned to you and your settings will not be applied to the ServicePoint you intended to change. 例如, FindServicePoint将尝试考虑http / https,要连接的主机,代理配置等问题。如果没有为FindServicePoint提供正确的参数,则很容易导致错误的ServicePoint返回。您和您的设置将不会应用于您要更改的ServicePoint

I would recommend that you use the FindServicePoint overload that takes an IWebProxy object to ensure that you get the right ServicePoint . 我建议您使用带有IWebProxy objectFindServicePoint重载,以确保获得正确的ServicePoint In most cases, you should be able to pass in WebRequest.DefaultWebProxy as the IWebProxy object. 在大多数情况下,您应该能够将WebRequest.DefaultWebProxy作为IWebProxy对象传递。

From the MSDN documentation of ServicePointManager.Expect100Continue, 从ServicePointManager.Expect100Continue的MSDN文档中,

Changing the value of this property does not affect existing ServicePoint objects. 更改此属性的值不会影响现有的ServicePoint对象。 Only new ServicePoint objects created after the change are affected. 仅更改后创建的新ServicePoint对象。 Therefore changing the value on the existing WCF client will have no effect. 因此,更改现有WCF客户端上的值将无效。 You need to create a new WCF client, then call GetData() 您需要创建一个新的WCF客户端,然后调用GetData()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM