Variable Substitution for Web Service URL

I’m consuming a web service (WCF) from a web application, so I added the web service as a web reference. Visual Studio creates the client wrapper classes from the wsdl URL, as it’s supposed to.

The problem is that we have multiple instances of the web service. The services are identical in schema but may be hitting different databases, etc. I would like that when I deploy the web application I can change where the service URL is by substituting the variable in the config file. The URL is set to dynamic (see http://stackoverflow.com/a/125411/1378356) but apparently there are still additional changes that are required. I know this because when I change the url in the properties pane in Visual Studio, I see that many other files have been modified as well. (It’s under source control.) Most of the files are the type which don’t get compiled, such as .xsd, .disco, .wsdl, .vbproj, so technically, I can set the Octopus deploy step to replace in ANY file, but that sounds like a pain. Moreover, Settings.Designer.vb gets changed as well, and that file is a code file, which gets compiled.

So the question is, how can I deploy the application in a manner where the URL of the service it consumes is decided upon at deployment time, not at development time?

(The code to consume the web service is actually not in the web application, but in a class library which it references locally, but I’m not sure why that should make any difference, see http://stackoverflow.com/q/24023486/1378356 .)

Hi Av,
When consuming a WCF service the Web Reference method has been depricated in favour of Service References. Both of these Visual Studio features basically just use the WSDL of the service endpoint you provide to generate a set of models and proxies to be used by your client. So long as the contracts beween your different service endpoint environments don’t change then they should be able to be used interchangeably. The endpoint config you want to change to allow pointing at different targets can be all contained in the app.config (or web.config if your consuming app is a website).

You do not need to Configure Service Reference in Visual Studio (as I assume you are doing) since this will just regenerate the contract & proxy classes that the client uses to wrap the remote endpoint. This url that is exposed via Visual Studio is really intended to be used for development purposes.

As an example, I have created a new Visual Studio project using the default WcfService generated by the sample app and started it running so it can be hit. I have then created a new project to consume this endpoint and clicked References -> Add Service Reference and entered the address (in this case http://localhost:2101/Service1.svc). Visual studio then queries the WSDL based on the provided address to generate a whole lot of files so that I can easily reference the contract in my code without having to build the clases, etc myself. My consuming code then looks like:

using (var client = new ServiceReference1.Service1Client("BasicHttpBinding_IService1"))
            {
                var xx = client.GetData(33);
            }

and my app.config (again generated by Visual Studio as part of its helpful Add Service Reference feature) looks like

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="BasicHttpBinding_IService1" />
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost:2101/Service1.svc" binding="basicHttpBinding"
                bindingConfiguration="BasicHttpBinding_IService1" contract="ServiceReference1.IService1"
                name="BasicHttpBinding_IService1" />
        </client>
    </system.serviceModel>
</configuration>

Notice that in code I reference BasicHttpBinding_IService1 which maps to the binding in the config. This is where, at runtime, your code will get its connection details. As you can see it is currently set to the value I supplied when adding the service reference. I can however change this address and this will be used when connecting. Now that the URI is in the configuration you can use Octopus Deploy’s variable substitution or config transform like any other value.

Remember all the code that Visual Studio generates for you is just scaffolding that you can create yourself manually if needed, its just there to help.

Further and more detailed information on WCF can be found all over the place online such as

And many, many more.

Let me know if you get stuck trying to perform the variable replacements in this config file, however much of it should be outline in our docs.
Cheers
Robert