An Extensive Examination of Web Services: Part 11By Scott Mitchell
As the previous ten installments in this article series have shown, the .NET Framework makes creating and consuming Web Services a walk in the park. Creating a Web Service is as easy as marking a class with the
WebServiceattribute; Web Services can be easily consumed because the .NET Framework includes tools to build proxy classes given a Web Service's WSDL file. All of the examples we have seen in previous installments in this article series have consumed Web Services from server-side code. That is, a Web Service is consumed when a postback occurs and server-side code in an ASP.NET page creates an instance of the proxy class and invokes one of its methods.
In 2007 Microsoft released their free ASP.NET AJAX framework, which simplifies
building AJAX-enabled ASP.NET applications (see An Introduction
to AJAX and Atlas with ASP.NET 2.0 for more information). The ASP.NET AJAX framework is best known for its
myriad of AJAX-enabled Web controls, but it also includes functionality to create and consume Web Services through
client-side script. Best of all, the workflow for creating script-accessible Web Services is very similar to creating
Web Services consumed through server-side .NET code. To mark a Web Service as being consumable from client script,
simply add the
ScriptService attribute; the service can be consumed through script via an auto-generated
Getting Started with Microsoft's ASP.NET AJAX Framework
The first step for creating script-accessible Web Services is to ensure that you have Microsoft's ASP.NET AJAX framework at your disposal. The AJAX framework does not support ASP.NET version 1.x; if you are using ASP.NET version 2.0 you'll need to download and install the free framework from http://www.asp.net/ajax/. (Refer to the Get Started with ASP.NET AJAX video for more information.) Future versions of ASP.NET will ship with the AJAX Framework, so there will be no need to download and install it separately.
Once you've installed the ASP.NET AJAX framework, launch Visual Studio. From the File menu choose to create a New Project.
The New Project dialog box will include an option to create an ASP.NET AJAX-Enabled Web Application. Choosing this option
will create a new Web Application Project that references the AJAX Framework assembly (
System.Web.Extensions assembly includes essential AJAX-related Web controls and the classes necessary to
create script-accessible Web Services. Additionally, this project types creates a default
with much additional markup. The markup that is germane to this article is the following:
These two bolded lines remove the default HTTP Handler for Web Service files (
.asmx) and replace it with
ScriptHandlerFactory from the ASP.NET AJAX framework. This handler determines whether or not the request
is coming from client-side script. If it is not, it dispatches the request to the default .NET Web Service handler.
If the request is coming from client-side script, however, it deserializes the incoming parameters, invokes the method,
serializes the response, and sends it back to the client.
Creating a Script-Accessible Web Service
Creating a script-accessible Web Service is just like creating a regular, server-side accessible Web Service. Start by adding a Web Service to your Web Application Project. This will create a class with the
WebServiceattribute. As we've seen from earlier installments, you can add methods to the Web Service by creating public methods marked with the
WebMethodattribute. At this point we have a Web Service that can be called from .NET code. To make it accessible from client-side script, simply add the
ScriptServiceattribute to the class (just like the
At the end of this article you'll find a downloadable demo application that includes a Web Service named
~/Services/Calculator.asmx. This Web Service is accessible from both .NET code and from client-script. It
offers four methods:
method takes as input two integer parameters and returns the sum, difference, product, or quotient. The following
code shows the class and the
Divide methods; the
methods have been removed for brevity.
Note the addition of the
ScriptService attribute. The attribute class is in the
namespace, which is why I have
using System.Web.Script.Services;. Each accessible method is marked with the
That's all there it to creating the script-accessible Web Service! It's just like creating a regular Web Service. The only
difference is the inclusion of the
Consuming the Web Service from Client-Side Script
To consume a script-accessible Web Service from client-side script, you'll need to start by adding a ScriptManager control to the page. The ScriptManager control is part of the ASP.NET AJAX framework that enables developers to perform AJAX-related operations, including invoking script-accessible Web Services.
From the ScriptManager control, we need to indicate that we want to be able to invoke the
Web Service. This is accomplished by adding a
ServiceReference element to the control's
calls the Web Service. Here's the abbreviated code from the client-side
Add_OnClick function, which runs
when the Add button is clicked:
To call the Web Service, simply reference the appropriate Web Service method like so:
Namespace.WebServiceName.Method(parameters, SuccessCallbackMethod, FailureCallbackMethod).
For this example, the Web Service's namespace is
ScriptServices.Services (to verify this, check the
value in the code listing in the "Creating a Script-Accessible Web Service" section); the Web Service name is
and the method to call is
Add. Two values are passed in as the parameters to
yValue). Web Service calls through script are asynchronous, meaning that control returns to the
browser immediately after the above bolded line is executed. When the Web Service returns, the
CalculationSuccessCallback function (which we need to create) is invoked:
serviceResults contains the actual value returned by the Web Service method (for
Add, it's the
sum of the two input parameters). This return value is then displayed in the results textbox at the bottom of the page.
Handling Web Service Invocation Errors
If the Web Service call completes as expected, the specified function (
CalculationSuccessCallback, in this case) is invoked. But what happens if something goes awry? Perhaps the web server that the Web Service runs on is down. Or maybe the executed Web Service method threw an exception. The
Dividemethod, for example, will bomb out if the user tries to divide by zero. How is such a situation handled in the client script?
If we do not modify our code at all, a failed Web Service invocation fails silently. The
function is never called. No script error is raised. It's as if the Web Service call was never made.
If you want to handle script errors, you need to instruct the proxy class to call a different method in the face of
an error. This can be accomplished by specifying the failure callback method much like we did with the successful callback method:
We then need to create this
CalculationFailedCallback method. The method is passed a
object that contains details about the exception.
The above function starts by displaying the exception message in a messagebox. It then displays the text, "THERE WAS AN ERROR" in the results textbox.