In this article, I will answer some of the common questions which most of the developers face while working with ASP.NET Ajax Web Services.
The first thing I would like to cover is the complete signature of the Web Service method call. Certainly, there are many references available including the ASP.NET Ajax Documentation; but none of them highlighted it.
As you can see, you can pass any contextual data when calling a Web Method. This contextual data along with the method name is available in both Success and Failure callbacks. This extra data becomes handy when you use the same callback function for multiple web methods.
Consider the following example: I have a single callback function, which is used to update the different parts of the same page.
Certainly, you can use the
set_defaultFailedCallback instead of specifying the same callback repeatedly. Note that
methodName is the Web Service method name. You can pass anything as the
userContext parameter; but it will never be passed to the web method.
The next issue I would like to cover is handling the timeout of a Web Service method call. In the early days of ASP.NET Ajax, there was a separate callback function to handle the timeout. With the final release, a timeout is handled in the
failedCallback, like so:
You can use the
set_timout of your Web Service class to increase the default timeout value. If you want to increase all of your Web Services timeouts, then use
Sys.Net.WebRequestManager.set_defaultTimeout(). This will also change the default timeout value of all your Ajax operations, including the UpdatePanel and manual invoking of Sys.Net.WebRequest.
Complex Data Type Interchange
In this section, I will show you how to implement some complex data types interchange with Web Services. Let's begin with arrays.
The above method is called as follows:
Now, let's see how to do the opposite: Pass an array to a web method.
We can pass the
names array like so:
Next, we will see how to pass and return a Dictionary object. Some of you might argue that having a Dictionary object in the method signature always returns a serialization exception in regular Web Services. The ASP.NET Ajax framework allows a Dictionary object in the method signature. Consider the following example, which returns the weathers of different cities of Bangladesh:
We can call this method and format the result as follows:
Let's see how to pass a dictionary to a web method.
We can pass the weathers to the above web methods like the following:
Serializing a complete Object Graph
In this section we will see how to return/pass a custom class using Web Services. By default, the ASP.NET Ajax Framework only generates top-level classes in the Web Service proxy. Consider the following web method:
Address is undefined:
Address is a child object of the Customer class, the framework does not include it in the client proxy. To resolve this issue, add the
GenerateScriptType attribute either in the web method or in the Web Service class:
By default the ASP.NET Ajax Framework serializes all the public fields and properties of custom classes in the client proxy. Sometimes we want to exclude a few of the public fields/properties of those custom classes. To do that, use the
However, this will not have any effect if your web method response format is set to
xml instead of default
json. In the former case, use the
XmlIgnore attribute like you do for regular Web Services.
Serialize incompatible types
In situation like these, the
Overriding the SupportedTypes property is mandatory. It instructs the ASP.NET Ajax Framework about the type the converter is responsible for, as in the following example:
If you are both accepting and returning the type, you will need to override both the getter and the setter. In our case we are only returning the Employee; thus we need to override the Serialize method and leave the others without any implementation, like so:
Serialize method is simply streamlining the hierarchical employee in a dictionary object. To ensure the converter is called when the employee object is serialized you have to register it in the web.config file:
You can have anything for the
name but the
Figure 1: Output obtained using a custom ASP.NET Ajax converter
Long Running Web Service Call
In this section I will show you how to display a progress indicator for a long running task, like the one shown in figure 2.
Figure 2: A progress indicator for a long running task
The design is very simple. First, we invoke a web method, which will start the lengthy task. It will create a status object that contains the progress information, which we will store in the ASP.NET cache. Next, we poll the task status by invoking another web method. Finally, we update the progress bar based upon the task progress. Let's take a peek at the Web Service code.
As you can see, we created the task ID based upon the user name to store it in the cache. Then we are doing some fake delay to simulate a real task and increasing the progress. Note that we cannot use the ASP.NET session, as the session access is always sequential. In the
GetTaskStatus method we are simply returning the status from the cache. Now let's examine the client side code.
We are first doing some UI initialization and starting the lengthy task. Then we create a timer by calling
setInterval, which polls the task status at two seconds interval. Once we get the status, we check whether the task is complete. If it isn't, we update the progress bar based upon its progress.
It is quite common to add AJAX support for our existing SOAP Web Service. Unfortunately the built-in
WebServiceProxy class does not support either the SOAP header or any custom HTTP header. I've developed a custom proxy which has built-in support for both. Consider the following Web Service:
You will be able to call this method with the following code:
Now let see how to pass a custom HTTP header with the new proxy. Consider the following web method:
You will be calling the above method with the following code:
The main issue is that you have to manually write the proxy class for the Web Service. Also, the return type is always XML instead of a JSON object. The following code shows the web proxy for the above Web Service:
You can also use the above proxy for old versions of ASP.NET projects with ASP.NET Ajax Client Library.
All the above issues are based on feedback from the ASP.NET Ajax WebService Forum. If you experienced any issues that I have missed, please let me know and I will cover it in the future.