1

The client application now I have to modify is deployed using ClickOnce and using code signed certificates and therefore we can’t change the app.config. But each client has their own WCF services, therefore we have to configure the proxy endpoint programmatically(dynamically) in code instead of using app.config. At the moment the proxy is created using app.config settings and work perfectly. Here is the 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>

current code to create proxy:

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

}

This works perfectly.

Now instead of using proxyEndPointConfigName I am converting everything in the app.config in the code. I have so far converted as follows but couldn’t find a way to replace andpointBehavior using code.

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;
    }

I searched the web and couldn’t find any sample using wshttpbinding and certificates. (There is a similar question found here How to create a WCF client without settings in config file? but it doesn’t discuss about endpoint behaviour and wshttpbinding.)

Sorry about this long question. I am trying to give complete details.

Can someone please show me how to add matching endpoint behavior in the app.config to ChannelFactory in the above method CreateProxy(,)? Thanks.

EDIT: Please note that in summary I want c# code on how to translate endpointbehaviours section given in the app.config above. Or any other way to dynamically change the service endpoint ?

Community
  • 1
  • 1
Dush
  • 1,185
  • 26
  • 29

0 Answers0