【问题标题】:Change WCF client host address - dynamic binding security更改 WCF 客户端主机地址 - 动态绑定安全
【发布时间】:2015-09-12 17:01:28
【问题描述】:

我经常想在测试期间更改 WCF 服务客户端的主机 URL。在我的配置中,我通常有这样的绑定:

  <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是只读的,只能在构造函数中设置。我可以使用正确的安全模式创建绑定,但随后我丢失了配置文件中配置的所有其他属性值。我不想尝试明确地复制它们。有没有办法使用配置文件的&lt;binding&gt; 创建一个新的 BasicHttpBinding,然后更改它的安全模式,以便我可以使用绑定来实例化 svc?

【问题讨论】:

    标签: c# wcf configuration


    【解决方案1】:

    下面是我如何做的一个例子:

    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();
    

    这样我可以简单地更改 web 或 app.config 中的服务 URL,而无需更改绑定、维护多个绑定或弄乱我的调用源代码。这让我们减少了在完成调试后必须记住的一件事,如果您的团队中有不守纪律的开发人员或不了解绑定配置的开发人员,这将特别方便。 CreateChannel 也是在运行时设置凭据的便利位置。

    【讨论】:

      【解决方案2】:

      我没有方便的服务来对此进行测试,但您可以执行以下操作:

      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();
      

      简而言之,在创建客户端之前完成所有绑定配置工作,因为您已经注意到,一旦创建了客户端通道,您就无法进行太多更改。

      【讨论】:

      • 我很困惑。我试过你的代码,它确实有效,但如果 Mode 属性在这里是可写的,它也应该在 ServiceClient 实例上是可写的。它是。我可以设置绑定的模式,或者在实例化 svc 后替换整个绑定本身。我昨天可以发誓它不会让我设置它们,并且描述说“设置......”而不是“获取或设置......”。无论如何,我不知道您可以创建传递配置名称的 BasicHttpBinding,这是我最初认为必要的方法的关键。如果可以的话,我会否决我自己的问题...
      猜你喜欢
      • 2012-01-14
      • 2011-04-25
      • 2012-08-25
      • 1970-01-01
      • 1970-01-01
      • 2020-02-24
      • 1970-01-01
      • 2016-03-30
      相关资源
      最近更新 更多