2015-06-25 65 views
0

我经常想在测试期间更改WCF服务客户端的主机URL。在我的配置,我通常有一个结合是这样的:更改WCF客户端主机地址 - 动态绑定安全

<basicHttpBinding> 
    <binding name="ListsSoap" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true"> 
     <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="5120000" maxNameTableCharCount="16384"/> 
     <security mode="Transport"> 
     <transport clientCredentialType="Ntlm"/> 
     </security> 
    </binding> 

这是很容易在运行时换出地址:

ServiceClient svc = new ServiceClient(); 
svc.Endpoint.Address = new EndpointAddress("http://wherever"); 

的问题是,如果我从https更改地址http,称该服务会爆炸说它期望https,因为它试图使用传输安全。

看来svc.Endpoint的Binding是只读的,只能在构造函数中设置。我可以使用正确的安全模式创建一个绑定,但是然后我失去了配置文件中配置的所有其他属性值。我不想尝试明确地复制它们。有没有办法使用配置文件<binding>创建一个新的BasicHttpBinding,然后改变它的安全模式,这样我就可以使用绑定实例化svc了?

回答

1

我没有方便的服务来进行测试,但你也许可以做到以下几点:

  1. 创建一个新的BasicHttpBinding,在配置名称 通过从您的配置文件。
  2. Security.Mode设置为None
  3. 将新绑定传递给服务客户端重载的构造函数,该构造函数采用绑定和端点地址。

事情是这样的:

BasicHttpBinding binding = new BasicHttpBinding("ListsSoap"); 
binding.Security.Mode = BasicHttpSecurityMode.None; 

ServiceClient svc = new ServiceClient(binding, new EndpointAddress("http://wherever")); 
svc.Open(); 

总之,做所有的绑定配置的东西,你创建的客户端之前,因为你已经注意到一旦客户端通道创建有没有什么可以更改。

+0

我很困惑。我试过你的代码,它确实有效,但是如果Mode属性在这里是可写的,它也应该可以在ServiceClient实例上写入。它是。我可以设置绑定的模式,或者在svc被实例化后替换整个绑定本身。我可以发誓昨天它不会让我设置它们,并且描述中说“设置...”而不是“获取或设置......”。无论如何,我不知道你可以创建BasicHttpBinding传递配置名称,这是我最初_thought_必须的方法的关键。如果我可以的话,我会投下我自己的问题。 – xr280xr

0

所以这里是我会怎么做一个例子:

public partial class ListsSoapClient 
{ 
    protected override ListsSoap CreateChannel() 
    { 
#if DEBUG 
     //When debugging, change the binding's security mode 
     //to match the endpoint address' scheme. 
     if (this.Endpoint.Address.Uri.Scheme == "https") 
      ((BasicHttpBinding)this.Endpoint.Binding).Security.Mode = BasicHttpSecurityMode.Transport; 
     else 
      ((BasicHttpBinding)this.Endpoint.Binding).Security.Mode = BasicHttpSecurityMode.None; 
#endif 

     return base.CreateChannel(); 
    } 
} 

所以我的代码来调用服务可以保持不变:

ServiceClient svc = new ServiceClient(); 
svc.Call(); 

这样我可以简单地改变服务URL中web或app.config,而不必更改绑定,维护多个绑定或混淆我的调用源代码。这使我们在完成调试后不得不记住要更改一次,如果您的团队中有不合逻辑的开发人员或不了解绑定配置的开发人员,这样做尤其方便。 CreateChannel也是在运行时设置凭据的便利场所。