C# – Changing WCF Service reference URL based on environment

cnetwcfweb.config

I have a web application that uses a number of WCF Services. I deploy my web application in various environments (dev, UAT, production etc). The URL of each WCF Service is different for each environment. I am using .NET 3.5 andbasicHttpBindings

The web application uses a framework to support machine-specific settings in my web.config file. When instantiating an instance of a WCF Service client I call a function that creates the instance of the WCF Service client using the constructor overload that takes the arguments:

System.ServiceModel.Channels.Binding binding,
System.ServiceModel.EndpointAddress remoteAddress

In essence the <system.serviceModel><bindings><basicHttpBinding><binding> configuration in web.config has been replicated in C# code.

This approach works well.

However, I now have to enhance this approach to work with a WCF service that uses an X509 certificate. This means that I have to replicate the following additional settings in web.config in C# code:

<!-- inside the binding section -->
<security mode="Message">
  <transport clientCredentialType="None" proxyCredentialType="None" realm="" />
  <message clientCredentialType="Certificate" algorithmSuite="Default" />
</security>


<behaviors>
  <endpointBehaviors>
    <behavior name="MyServiceBehaviour">
      <clientCredentials>
        <clientCertificate storeLocation="LocalMachine" storeName="My"
          x509FindType="FindByThumbprint" findValue="1234abcd" />
        <serviceCertificate>
          <defaultCertificate storeLocation="LocalMachine" storeName="My"
            x509FindType="FindByThumbprint" findValue="5678efgh" />
          <authentication trustedStoreLocation="LocalMachine"
            certificateValidationMode="None" />
        </serviceCertificate>
      </clientCredentials>
    </behavior>
  </endpointBehaviors>
</behaviors>

I am having some difficulty figuring out how to code this configuration in C#.

Two questions

  • Can anyone recommend a better approach for managing WCF Service reference URLs across multiple environments?
  • Alternatively, any suggestions on how to replicate the above web.config section in C# will be welcomed

Best Answer

One possible approach would be to "externalize" certain parts of your <system.serviceModel> configuration into external files, one per environment.

E.g. we have "bindings.dev.config" and "bindings.test.config", which we then reference in our main web.config like this:

<system.serviceModel>
  <bindings configSource="bindings.dev.config" />
</system.serviceModel>

That way, all you need to change from DEV to PROD is this one line of config XML.

Basically, in .NET 2.0 config, any configuration element can be "externalized". You cannot however externalize configGroups (such as "system.serviceModel") directly - you have to be on the "configuration element" level.

Marc

EDIT: OK, so NO config edit changes to switch between environments..... In that case, you probably have to dream up a naming scheme, e.g. name your bindings, behaviors and endpoints in such a way, that you can distinguish them at runtime.

Something like:

<bindings>
  <binding name="Default_DEV">
    .....
  </binding>
  <binding name="Default_PROD">
    .....
  </binding>
</bindings>

that way, you could build up the name of the element you want (e.g. binding "Default_PROD") from your code and the environment you're running in, and then grab the according config from the config file which contains all the config settings for all environments.

Related Topic