如何在没有任何配置文件的情况下,在代码中添加WCF自定义绑定元素扩展客户端?
形势 我有一个客户端库,它使用Windows Azure AppFabric服务总线NetCPRelayBinding连接到端点。客户端库由应用程序托管,该应用程序不一定是.NET应用程序。无论如何,app.config是不可能的,这意味着一切都应该用代码配置 Machine.config是一个选项,但如果可以避免,则更好。本地定制代理或前端服务器可能是另一种选择,但在彻底改变体系结构之前,我想先探讨一下这个选择 系统绑定没有问题,但我还没有想出或找到解决方案,如何在代码中将以下配置添加到ChannelFactory:如何在没有任何配置文件的情况下,在代码中添加WCF自定义绑定元素扩展客户端?,wcf,configuration,wcf-binding,servicebus,Wcf,Configuration,Wcf Binding,Servicebus,形势 我有一个客户端库,它使用Windows Azure AppFabric服务总线NetCPRelayBinding连接到端点。客户端库由应用程序托管,该应用程序不一定是.NET应用程序。无论如何,app.config是不可能的,这意味着一切都应该用代码配置 Machine.config是一个选项,但如果可以避免,则更好。本地定制代理或前端服务器可能是另一种选择,但在彻底改变体系结构之前,我想先探讨一下这个选择 系统绑定没有问题,但我还没有想出或找到解决方案,如何在代码中将以下配置添加到Cha
<extensions>
<bindingElementExtensions>
<add name="tcpRelayTransport" type="Microsoft.ServiceBus.Configuration.TcpRelayTransportElement, Microsoft.ServiceBus, Version=1.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</bindingElementExtensions>
<bindingExtensions>
<add name="netTcpRelayBinding" type="Microsoft.ServiceBus.Configuration.NetTcpRelayBindingCollectionElement, Microsoft.ServiceBus, Version=1.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</bindingExtensions>
</extensions>
您可以通过编写自定义服务主机工厂,通过代码添加绑定元素扩展。类似的问题也得到了回答 根据您的WCF服务类型,在编写自定义服务主机工厂时,您只需要继承适当的servicehostfactory类。例如,如下所示:
此处提供了不带配置的示例: 以下是代码片段:
ChannelFactory<IEchoChannel> channelFactory = null;
IEchoChannel channel = null;
try
{
//Create a Behavior for the Credentials
TransportClientEndpointBehavior sharedSecretServiceBusCredential = new TransportClientEndpointBehavior();
sharedSecretServiceBusCredential.TokenProvider = TokenProvider.CreateSharedSecretTokenProvider(issuerName, issuerSecret);
//Create a Channel Factory
channelFactory = new ChannelFactory<IEchoChannel>(new NetTcpRelayBinding(), new EndpointAddress(serviceAddress));
channelFactory.Endpoint.Behaviors.Add(sharedSecretServiceBusCredential);
LogMessage("Opening channel to: {0}", serviceAddress);
channel = channelFactory.CreateChannel();
channel.Open();
LogMessage("Sending: {0}", echoTextBox.Text);
string echoedText = channel.Echo(echoTextBox.Text);
LogMessage("Received: {0}", echoedText);
echoTextBox.Text = string.Empty;
LogMessage("Closing channel");
channel.Close();
LogMessage("Closing factory");
channelFactory.Close();
}
catch (Exception ex)
{
LogMessage("Error sending: {0}<br/>{1}", ex.Message, ex.StackTrace.Replace("\n", "<br/>"));
// Close the channel and factory properly
if (channel != null)
{
CloseCommunicationObject(channel);
}
if (channelFactory != null)
{
CloseCommunicationObject(channelFactory);
}
}
ChannelFactory ChannelFactory=null;
IEchoChannel=null;
尝试
{
//创建凭据的行为
TransportClientEndpointBehavior sharedSecretServiceBusCredential=新TransportClientEndpointBehavior();
sharedSecretServiceBusCredential.TokenProvider=TokenProvider.CreateSharedSecretTokenProvider(issuerName,issuerSecret);
//创建渠道工厂
channelFactory=newchannelfactory(new nettcpreaybinding(),newendpointaddress(serviceAddress));
channelFactory.Endpoint.Behaviors.Add(sharedSecretServiceBusCredential);
LogMessage(“打开到:{0}的通道”,serviceAddress);
channel=channelFactory.CreateChannel();
通道打开();
LogMessage(“发送:{0}”,echoTextBox.Text);
字符串echotedtext=channel.Echo(echoTextBox.Text);
日志消息(“收到:{0}”,回显文本);
echoTextBox.Text=string.Empty;
日志信息(“关闭通道”);
channel.Close();
日志信息(“关闭工厂”);
channelFactory.Close();
}
捕获(例外情况除外)
{
LogMessage(“发送错误:{0}
{1}”,例如Message,例如StackTrace.Replace(“\n”,“
”);
//正确关闭通道和工厂
如果(通道!=null)
{
封闭通信对象(通道);
}
if(channelFactory!=null)
{
密切沟通对象(渠道工厂);
}
}
这是现在已经测试过的解决方案。希望它能清楚地说明问题到底是什么,也许它能帮助其他人解决类似的问题。归功于有时间调查问题的同事
解决方案是动态编辑配置,并添加对所需的绑定元素扩展的引用(在任何层中都没有app.config,或者在客户端计算机中也没有更改machine.config):
不过,还是要感谢每一位试图帮助我的人 看看用c#绑定NetCpreayBinding的原因是什么code@Rajesh该示例仍然假设服务总线绑定扩展(如NetCPRelayBinding)位于app.config或machine.config中。在这种情况下,您的问题是否意味着如何通过C代码添加bindingElementExtensions?@Rajesh是,我认为这应该是更准确的标题更正。这些都是很好的例子,但它们适用于服务器端的ServiceHost,这不是问题。我的问题在于客户端(ChannelFactory),谢谢,但是这个示例在WebRole的web.config中仍然有bindingExtensions元素,这就是问题所在。
var service = ServiceModelSectionGroup.GetSectionGroup(ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None));
var tcpRelayTransportExtension = new ExtensionElement("tcpRelayTransport", "Microsoft.ServiceBus.Configuration.TcpRelayTransportElement, Microsoft.ServiceBus, Version=1.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
var netTcpRelayTransportExtension = new ExtensionElement("netTcpRelayBinding", "Microsoft.ServiceBus.Configuration.NetTcpRelayBindingCollectionElement, Microsoft.ServiceBus, Version=1.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
if (service.Extensions.BindingElementExtensions.ContainsKey(tcpRelayTransportExtension.Name) == false)
{
service.Extensions.BindingElementExtensions.Add(tcpRelayTransportExtension);
}
if (service.Extensions.BindingElementExtensions.ContainsKey(netTcpRelayTransportExtension.Name) == false)
{
service.Extensions.BindingElementExtensions.Add(netTcpRelayTransportExtension);
}