by May 5, 2003 0 comments



Last time we saw how to invoke Web services asynchronously. Asynchronous invocation makes an application more responsive since the call does not block the caller, and frees them to continue with their work. This month, we shall continue our interaction with Web services and discuss some tips and tricks that can help make our life easier while working with them. So, without further delay, lets have a look at them.

Dynamic webservice URIs
Generally, Web services are expected to be located at a fixed URI, once they have been made public and other developers are actively using them within their applications. However, equally true is the fact that, in future, the URI of the webservice might change. This change can severely affect the applications that have the webservice URI hard coded. 

For instance, when you typically use the WSDL utility to create a proxy for a webservice, you end up creating a hard coded webservice invocation mechanism since the webservice URI is set in the proxy, in the constructor of the webservice class. Here’s a simple webservice that has a webmethod Add which adds the two numbers passed to it as parameters and returns their sum:

<%@ WebService language=”C#” class=”CTest” %>
using System;
using System.Web.Services;
using System.Xml.Serialization;
public class CTest {
[WebMethod]
public int Add(int a, int b) {
return a + b;
}
}

If you use the WSDL utility to create a proxy for this webservice, you shall see in the generated source code that the class constructor will be hard setting the webservice URI, as shown in the C# excerpt below:

/// <remarks/>
public CTest() {
this.Url = “http://127.0.0.1/test/ctest.asmx”;
}

The Url property contains the URI from which the webservice shall be invoked. Now, traditionally, one would compile this proxy, produce a DLL, add a reference to the DLL from the assembly using the webservice and the invocation works. But if the webservice URI changes, the change will not be reflected in the client application that was referencing the produced proxy since it was compiled with the hard coded setting. Thus, the application shall break up.

In order to handle such a scenario, store the URI of the webservice in a configuration file and tell WSDL, using the /urlkey switch, to read it from there at runtime. Assuming that your application configuration file would be structured like this:

<configuration>
<appSettings>
<add key=”CTestURI”
value=”<http://localhost/mywebservice/service1.asmx>” />
</appSettings>
</configuration>

the key, CTestURI, will give the URI from which to invoke the webservice. All you need to do is change the URI here, and your client application will use the new URI, without breaking up. 

So, in order to do this, you create your proxy in a slightly different manner, as shown below:

WSDL /l:cs /urkey:CTestURI http://127.0.0.1/test/ctest.asmx

The resulting proxy has a slightly different class constructor, as evident from the excerpt below:

/// <remarks/>
public CTest() {
string urlSetting =
System.Configuration.ConfigurationSettings.AppSettings[“CTestURI”];
if ((urlSetting != null)) {
this.Url = urlSetting;
}
else {
this.Url = “http://127.0.0.1/test/ctest.asmx”;
}
}

As can be noticed, the constructor is intelligent enough to read the configuration file key, which we specified at command line of WSDL invocation, and attempts to read the entry there. If one is present, the Url property is set to the one read from the configuration file. Incase one isn’t specified, the Url property is then set to the default value of the URI that was specified at the command line, at which the webservice is present.

Compile the proxy to a DLL, reference it in your client application and have the application configuration file in place with the above setting. Now, to have a dynamically relocating webservice used by your application, you need to have the new URI specified in the application configuration file. No more client application breakdowns because a webservice got relocated!
What we just discussed is one simple way to handle dynamic webservice relocations. Another, more sophisticated way to do the same is to use UDDI (Universal Discovery Description and Integration) SDK (that you may download from http://msdn.microsoft. com/library/default.asp?url=/downloads/list/websrvuddi.asp) and dynamically query the UDDI server for a webservice URI at runtime and have the class constructor set the Url property to the URI returned by the UDDI server instead of reading it from a configuration file. This eases the task of reflecting the change in the URI, without manual changes to be done in the application configuration file.

Generating proxy 
There are times when the applications requiring the use of webservices are behind proxy servers. In such a case, we use a slightly different approach while creating the proxy for the webservice as shown below:

C:\KGK\Test>wsdl /l:cs /proxy:proxy.mydomain.com http://127.0.0.1/test/ctest.asmx

Using the /proxy switch, we tell WSDL to use the specified proxy server to connect to the webservice. Incase the proxy server requires you to authenticate, you may use the /proxyusername and /proxypassword switches to specify the required authentication credentials.

Similarly, in case the server hosting the webservice requires you to authenticate before the webservice can be used and invoked, the /username and /password switches indicate WSDL to authenticate against the server, before attempting to produce the proxy for the
webservice.

Stateless WebServices 
Webservices are stateless in nature, and consequently, do not maintain state information across calls. That’s why they have no notion of properties, like traditional components that we create. Each method invocation of the webservice will be, in all probability, against any ASP.NET runtime worker thread. Thus, webservices should be designed such that their methods expose functionalities/services that adhere to such stateless design philosophy.

An example of this could be a webservice exposing a webmethod that authenticates a credit card number, since such functionality only a single piece of information, the credit card number that can be passed to it as a parameter, without requiring some state information to be maintained from previous calls. 

This completes our two-part discussion of advanced webservice development. In future we will see how .NET enables us to develop applications for mobile devices, using the .NET Compact Framework. We shall exemplify the same using Microsoft’s latest development tool, Visual Studio .NET 2003 that eases and integrates this development.

Kumar Gaurav Khanna, 
Microsoft MVP, runs wintoolzone.com

No Comments so far

Jump into a conversation

No Comments Yet!

You can be the one to start a conversation.

<