更改 WCF 客户端主机地址 - 动态绑定安全
Change WCF client host address - dynamic binding security
我经常想在测试期间更改 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是只读的,只能在构造函数中设置。我可以使用正确的安全模式创建绑定,但随后我丢失了在配置文件中配置的所有其他 属性 值。我不想尝试显式复制它们。有没有办法使用配置文件的 <binding>
创建一个新的 BasicHttpBinding 然后更改它的安全模式以便我可以使用绑定实例化 svc?
我没有方便的服务来测试它,但您可以执行以下操作:
- 新建一个
BasicHttpBinding
,传入配置名称
从你的配置文件。
- 将
Security.Mode
设置为 None
。
- 将新绑定传递给采用绑定和端点地址的服务客户端重载构造函数。
像这样:
BasicHttpBinding binding = new BasicHttpBinding("ListsSoap");
binding.Security.Mode = BasicHttpSecurityMode.None;
ServiceClient svc = new ServiceClient(binding, new EndpointAddress("http://wherever"));
svc.Open();
简而言之,在创建客户端之前完成所有绑定配置工作,因为正如您已经注意到的那样,一旦创建了客户端通道,您就无法更改太多。
下面是我将如何做的一个例子:
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 中的服务 URL 或 app.config,而无需更改绑定、维护多个绑定或弄乱我的调用源代码。这让我们少了一件必须记住在完成调试后更改回来的事情,如果您的团队中有散漫的开发人员或不了解绑定配置的开发人员,这将特别方便。 CreateChannel 也是在运行时设置凭据的便利位置。
我经常想在测试期间更改 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是只读的,只能在构造函数中设置。我可以使用正确的安全模式创建绑定,但随后我丢失了在配置文件中配置的所有其他 属性 值。我不想尝试显式复制它们。有没有办法使用配置文件的 <binding>
创建一个新的 BasicHttpBinding 然后更改它的安全模式以便我可以使用绑定实例化 svc?
我没有方便的服务来测试它,但您可以执行以下操作:
- 新建一个
BasicHttpBinding
,传入配置名称 从你的配置文件。 - 将
Security.Mode
设置为None
。 - 将新绑定传递给采用绑定和端点地址的服务客户端重载构造函数。
像这样:
BasicHttpBinding binding = new BasicHttpBinding("ListsSoap");
binding.Security.Mode = BasicHttpSecurityMode.None;
ServiceClient svc = new ServiceClient(binding, new EndpointAddress("http://wherever"));
svc.Open();
简而言之,在创建客户端之前完成所有绑定配置工作,因为正如您已经注意到的那样,一旦创建了客户端通道,您就无法更改太多。
下面是我将如何做的一个例子:
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 中的服务 URL 或 app.config,而无需更改绑定、维护多个绑定或弄乱我的调用源代码。这让我们少了一件必须记住在完成调试后更改回来的事情,如果您的团队中有散漫的开发人员或不了解绑定配置的开发人员,这将特别方便。 CreateChannel 也是在运行时设置凭据的便利位置。