Setting Web Service References Dynamically
I recently finished a public business site for a client that used a Web Service to access the client's back-end database. In addition to the web site itself, I wrote the ASP.NET Web Service in C#. The Web Service was relatively simple and only needed to make a few references into the clients Managed C++ (.NET) interface modules. The client's Managed C++ further interfaced to some legacy business logic DLLS written in unmanaged C++.
I started by creating the Web Service project on my "localhost" workstation. The code simply returned some test data without actually calling the client's Managed C++ modules. When I created the web application project, I simply did a right-click in the Solution Explorer on the "Web References" item and added the reference to my localhost Web Service. As usual it created a web reference named "localhost".
After I added functionality to the Web Service, I deployed a version of the service to one of the clients test servers. I wanted to keep my "localhost" reference for testing, so I added a new web reference to the client's site (acmeco.com). As expected, I got a new web reference named "com.acmeco".
I accessed the appropriate Web Service with a compile-time "#define / #if" within the logic of my web site's code; but I was unhappy with this source code change to select the appropriate Web Service. By the time the client wanted to another optional server to host the Web Service, and I now had three choices, I decided to try and make the selection of the Web Service location dynamic.
My first solution was way overkill. I went to my old familiar design patterns and used a modified bridge-pattern class to create an object that would access the appropriate web reference at run-time. This seemed like too many concrete classes for this simple problem.
Finally I was looking at the on-line help (RTFM), and I found a method of the class (SoapHttpClientProtocol) from which my web reference object was created that allowed me to set the "Url" that specified the location of the Web Service. At this point, I realized I could delete all but one of my web references, and then set the "Url" at run-time to choose the appropriate Web Service. I simply renamed my one remaining web reference (right click in the Solution Explorer) from "localhost" to a common name, like "AcmecoService". I then set the "AmcecoService" object's "Url" at run-time from a value stored in "appSettings" of the web.config file.
service = new Acmeco.AcmecoService();
service.Timeout = 10000;
service.Url = ConfigurationSettings.AppSettings["AcmecoWebServiceUrl"];
This solution may be obvious to many, especially those that read (and retain) all of the .NET Web Service/Reference documentation. For me, it was a real simplification of a solution to an annoying problem.
Update to this Article (9/15/02)
Oopps...I found an even easier method to set the Web Service Url dynamically using Visual Studio properties.
And now I've found that the Visual Studio is way ahead of me. Simply choose the properties of the web service and change the "Url Behavior" from "Static" to "Dynamic". This will automatically create an entry in the <appSettings> section of the Web.Config file that contains the Url string. The constructor of the Web Service proxy class is automatically changed to set the Url property to the value stored in Web.Config.
Send your comments and let me know what you think of this article: firstname.lastname@example.org
Steve Sharrock - www.AspAlliance.com/shark