views:

1195

answers:

2

I have a web application that exposes web services using WCF and wsHttpBindings. It is possible to have the application on different machines and different urls. This would mean the WCF service location would be different for each.

I am building a Windows Service that will reference each application and perform a task. Each task needs to call a service on the web application. I understand that the bindings are all setup in the app.config, but is there a simpler way to call the service dynamically, or how would I structure the app.config?

<webApplication WebServiceUrl="http://location1.com/LunarChartRestService.svc" />
<webApplication WebServiceUrl="http://location2.com/LunarChartRestService.svc"/&gt;
A: 

From your description, it sounds as if all servers are exposing the same service contract. If so, you could very well just declare multiple endpoints in your web.config and choose one at runtime based on the endpoint name.

Of course, it may be that you prefer not to deal with that part of the WCF configuration and would rather just have a simpler list of URLs and be done with it. That's perfectly possible as well; you just need to do a little bit more work on the code side to instantiate the client side proxies / channel objects.

tomasr
do you know of any examples of doing it the "simpler way", and of accessing/using multiple endpoints at runtime?
mickyjtwin
the service setup on the web application is wshttp as well, not basic.
mickyjtwin
There are several ways, this just being one of them: http://msdn.microsoft.com/en-us/library/ms734681.aspx
tomasr
+1  A: 

Your client's config file could look something like this:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <client>
      <endpoint name="Endpoint1"
                address="http://location1.com/LunarChartRestService.svc"
                binding="wsHttpBinding"
                contract="(whatever-your-contract-is)" />
      <endpoint name="Endpoint2"
                address="http://location2.com/LunarChartRestService.svc"
                binding="wsHttpBinding"
                contract="(whatever-your-contract-is)" />
      <endpoint name="Endpoint3"
                address="http://location3.com/LunarChartRestService.svc"
                binding="wsHttpBinding"
                contract="(whatever-your-contract-is)" />
    </client>
  </system.serviceModel>
</configuration>

Then in code, you can create such an endpoint (client proxy) based on its name and thus you can pick whichever location you need. There's nothing stopping you from creating multiple client proxies, either! So you can connect to multiple server endpoints using multiple client proxies, no problem.

Alternatively, you can of course also create an instance of "WsHttpBinding" and "EndpointAddress" in code, and set the necessary properties (if any), and then call the constructor for the client proxy with this ready made objects, thus overriding the whole app.config circus and creating whatever you feel is needed:

EndpointAddress epa = 
    new EndpointAddress(new Uri("http://location1.com/LunarChartRestService.svc"));
WSHttpBinding binding = new WSHttpBinding();

Marc

marc_s
I am having trouble finding examples of creating the ClientProxy, the point in which the call is made to return the results.
mickyjtwin
If you have your service up and running, you can have either Visual Studio create your client (by right-clicking on your project, and selecting "Add Service Reference"), or you can use the command-line utility "svcutil" to do the same. This will create the client side proxy, which will have the necessary constructors.
marc_s
But if I add a Service Reference, that is being specific to an endpoint correct? I need it so that the endpoint is configurable.
mickyjtwin
Hi Micky, if you need to be able to determine the endpoint dynamically at runtime, use the code-based approach. You can create a new instance of an EndpointAddress, a binding, and with these two, a new client proxy.
marc_s
Adding the service reference to your project just creates all the necessary "plumbing" so you can then programmatically create your client endpoints and dynamically use whatever URL's you have configured elsewhere.
marc_s
Do you know of any examples that would demonstrate this?
mickyjtwin
Well, you can see the two lines of codes necessary in my posting - create a EndpointAddress with the URL you need, create a wsHttpBinding instance, and then your client proxy should have a constructor which takes these two elements and creates a client proxy based on those settings.
marc_s