Dynamically set endpoint address in wcf client (with net tcp binding)

Jen picture Jen · Aug 31, 2012 · Viewed 12.3k times · Source

So I'm not overly familiar with WCF and all the stuff I've googled hasn't helped me with how to achieve what I need. Sorry if this is a dumb question :)

Basically there is a server app with services exposed with WCF (net tcp binding). I've written a new console app and I need to call the service. So I can achieve this by adding a dll for the proxy project we have and by adding a bunch of config files (such as WCFClientBindings, WCFClientEndPoints). If I use a defined end point then I can call code like this:

using (var partyProxy = new PartyControllerProxy())
            {
                // execute server method 
                partyProfile = partyProxy.GetLatestPartyProfile(context, parsedParameters.PartyId);
            }

However the app is supposed to be able to call the hostname that is passed in as a command line argument.

So whilst my app works with a defined endpoint:

<client>
  <endpoint
  name="IPartyControllerEndpoint"
  address="net.tcp://localhost:46000/ServiceInterface/PartyController.svc"
  binding="customBinding" bindingConfiguration="DefaultNetTcpBindingConfiguration"
  contract="CompanyA.Service.Product.Core.Contracts.IPartyController"
  behaviorConfiguration="DefaultEndpointBehavior">
  </endpoint>
</client>

I need to be able to update the localhost hostname to be potentially something else. Am hoping that security doesn't trip me up :)

The examples I've seen seem to instantiate the client/proxy by passing in the "dynamic" binding and address, but our proxy class doesn't accept those. Isn't there a way to update the address of the endpoint (at runtime) before calling the "proxy" class ? The only other examples I've seen have involved instantiating a new ServiceHost - but that doesn't sound very appropriate for the client :)

Thanks!

Edit - OK here's the syntax that seems to work nicely. It's a little different to the answer I accepted, but that approach was the way to go :)

using (ChannelFactory<IPartyController> factory = new ChannelFactory<IPartyController>("IPartyControllerEndpoint"))
        {
            EndpointAddress address = new EndpointAddress(String.Format("net.tcp://{0}/ServiceInterface/PartyController.svc", parsedParameters.HostName));
            IPartyController channel = factory.CreateChannel(address);

            partyProfile = channel.GetLatestPartyProfile(context, parsedParameters.PartyId);
            ((IClientChannel)channel).Close();
        }

Answer

Brad picture Brad · Aug 31, 2012

You could create a ChannelFactory.

Along with your standard client, WCF WSDLs will also provide an interface class for the client.

EndpointAddress address = new EndpointAddress("http://dynamic.address.here");
        using (ChannelFactory<IPartyControllerChannel> factory = new ChannelFactory<IPartyControllerChannel>("IPartyControllerEndpoint", address))
        {

            using (IPartyControllerChannel channel = factory.CreateChannel())
            {
                channel.GetLatestPartyProfile(context, parsedParameters.PartyId);
            }
        }