如何使用ChannelFactory创建具有端点行为的WCF客户端代理,而不使用app.config设置

时间:2014-10-16 12:52:19

标签: c# wcf proxy wcf-binding wcf-security

现在我必须修改的客户端应用程序使用ClickOnce并使用代码签名证书进行部署,因此我们无法更改app.config。但是每个客户端都有自己的WCF服务,因此我们必须在代码中以编程方式(动态)配置代理端点,而不是使用app.config。 目前,使用app.config设置创建代理并完美运行。这是app.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
  <client>
    <endpoint address="http://webserveraddress:1680/Services/Service.svc"
            behaviorConfiguration="wsHttpSyncBehavior"
            binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ISqlContract"
            contract="Company.Library.ISqlContract" name="WSHttpBinding_EndProxy">
      <identity>
        <dns value="ServerCertName"/>
      </identity>
    </endpoint>

  </client>

  <!--Bindings used by end points-->
  <bindings>
    <wsHttpBinding>
      <!-- Service end point-->
      <binding name="WSHttpBinding_ISqlContract" closeTimeout="00:01:00" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:05:00"
             bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
             maxBufferPoolSize="524288" maxReceivedMessageSize="10485760" messageEncoding="Text" textEncoding="utf-8"
             useDefaultWebProxy="true" allowCookies="false">
      <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="10485760" maxNameTableCharCount="16384"/>
      <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false"/>
      <security mode="Message">
        <transport clientCredentialType="Windows" proxyCredentialType="None" realm=""/>
        <message clientCredentialType="Certificate" negotiateServiceCredential="true" algorithmSuite="Default"/>
      </security>
    </binding>
  </wsHttpBinding>
</bindings>


<behaviors>
  <endpointBehaviors>
    <behavior name="wsHttpSyncBehavior">
      <clientCredentials>
        <clientCertificate findValue="ClientCertName" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My"/>
        <serviceCertificate>
          <authentication certificateValidationMode="None"/>
        </serviceCertificate>
      </clientCredentials>
    </behavior>
  </endpointBehaviors>
</behaviors>
</system.serviceModel>
</configuration>

创建代理的当前代码:

Public void CreateProxy(string proxyEndPointConfigName,string  clientCertificateName)
{
   ChannelFactory<ISqlSyncContract> factory = new ChannelFactory<ISqlSyncContract>(proxyEndPointConfigName);
        ServiceEndpoint e1 = factory.Endpoint;
        factory.Credentials.ClientCertificate.SetCertificate(
            StoreLocation.LocalMachine,
            StoreName.My,
            X509FindType.FindBySubjectName,
            clientCertificateName);

        ISqlSyncContract channel = factory.CreateChannel();

 //more code here

}

这很有效。

现在我没有使用proxyEndPointConfigName,而是在代码中转换app.config中的所有内容。我到目前为止转换如下,但无法找到使用代码替换andpointBehavior的方法。

Public void CreateProxy(string url,string  clientCertificateName)
{
  WSHttpBinding wsBinding = this.fillWsHttpBinding ();
  EndpointAddress remoteAddress = new EndpointAddress(new Uri(url), EndpointIdentity.CreateDnsIdentity(clientCertificateName));

  ChannelFactory<ISqlSyncContract> factory = new ChannelFactory<ISqlSyncContract>( wsBinding, remoteAddress);

  factory.Endpoint.Behaviors.Add(/*????how do I add code here???? */)
        factory.Credentials.ClientCertificate.SetCertificate(
            StoreLocation.LocalMachine,
            StoreName.My,
            X509FindType.FindBySubjectName,
            clientCertificateName);

        ISqlSyncContract channel = factory.CreateChannel();

    //more code here
}

private WSHttpBinding fillWsHttpBinding()
    {

        WSHttpBinding wsBinding = new WSHttpBinding();
        wsBinding.CloseTimeout = new TimeSpan(0, 1, 0);
        wsBinding.OpenTimeout = new TimeSpan(0, 10, 0);
        wsBinding.ReceiveTimeout = new TimeSpan(0, 10, 0);
        wsBinding.SendTimeout = new TimeSpan(0, 5, 0);
        wsBinding.BypassProxyOnLocal = false;
        wsBinding.TransactionFlow = false;
        wsBinding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
        wsBinding.MaxBufferPoolSize = 524288L;
        wsBinding.MaxReceivedMessageSize = 10485760L;
        wsBinding.MessageEncoding = WSMessageEncoding.Text;
        wsBinding.TextEncoding = Encoding.UTF8;
        wsBinding.UseDefaultWebProxy = true;
        wsBinding.AllowCookies = false;

        wsBinding.ReaderQuotas.MaxDepth = 32;
        wsBinding.ReaderQuotas.MaxStringContentLength = 8192;
        wsBinding.ReaderQuotas.MaxArrayLength = 10485760;
        wsBinding.ReaderQuotas.MaxNameTableCharCount = 16384;

        wsBinding.ReliableSession.Ordered = true;
        wsBinding.ReliableSession.InactivityTimeout = TimeSpan.FromMinutes(10);
        wsBinding.ReliableSession.Enabled = false;

        wsBinding.Security.Mode = SecurityMode.Message;
        wsBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
        wsBinding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
        wsBinding.Security.Transport.Realm = "";

        wsBinding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;
        wsBinding.Security.Message.NegotiateServiceCredential = true;
        wsBinding.Security.Message.AlgorithmSuite = System.ServiceModel.Security.SecurityAlgorithmSuite.Basic256;

        return wsBinding;
    }

我在网上搜索过,无法使用wshttpbinding和证书找到任何示例。 (这里有一个类似的问题How to create a WCF client without settings in config file?,但它没有讨论端点行为和wshttpbinding。)

对这个长问题感到抱歉。我想提供完整的细节。

有人可以告诉我如何在上面的方法CreateProxy(,)中将app.config中匹配的端点行为添加到ChannelFactory中吗? 感谢。

修改 请注意,总结一下,我想要在上面的app.config中给出关于如何翻译endpointbehaviours部分的c#代码。或者以其他方式动态更改服务端点?

0 个答案:

没有答案