Introduction
In this example we will access a Web Service created in C# from an HTML client. The client does not use .Net Framework directly and instead accesses the Web Service functionality using the DHTML behavior.
Definitions
Web Services are defined as programmable application logic that is accessible using standard Internet protocols.
DHTML behaviors are components that encapsulate functionality on a page. DHTML behaviors are available in IE5.5 and above. To be able to use the behavior in a Web Page in IE5.5, you will need to download the WebService.htc behavior file and save it in the same folder as your html page. The file can be downloaded from the following location: http://msdn.microsoft.com/downloads/samples/internet
/behaviors/library/webservice/webservice.htc
Program Details
Let's delve into the details of our program.
Step 1: Create the Web Service
Create the file that exposes our Web Service function using your favorite text editor or Visual Studio.Net. Shown below is the code for the Web Service.
<%@ WebService Language="C#" class="TestWS" %>
using System;
using System.Web.Services;
using System.Web.Mail;
[WebService] public class TestWS : System.Web.Services.WebService
{
[WebMethod] public int Add(int num1, int num2)
{
return num1 + num2;
}
}
Code Listing: Save as TestWS.asmx
The web service "TestWS" is very simple - it exposes only one function "Add" which accepts 2 integers as input and returns their sum as the output.
Step2 : Create the HTML Client
First we specify the web service behavior in the html file as follows
<div id="service" style="behavior:url(webservice.htc)" onresult="onWSresult()">
</div>
The id specified for this element to reference the element in script.
Next we map the web service URL to a user-friendly name ("Calculator" in this case).
We add this code in the OnLoad handler for the page to ensure that the web service is mapped before any methods are invoked on the web service.
service.useService('http://localhost/site/code/testws.asmx?WSDL','Calculator');
Now that the webservice is setup for access, we invoke the web service methods asynchronously in two steps. The advantage of asynchronous invocation is that the web page does not have to keep waiting for the web service to return. In the first step, the web method is invoked. A call back function is specified and when the web service completes execution, the callback function gets executed. As a second step, the call back function (or an "onresult" event, if no callback function is specified) gets fired when the web service returns after execution or a timeout error occurs.
The code to actually invoke the Web Service's web method is shown below. The web method is invoked when the "Add Numbers" button is clicked.
The input parameters to the callService method are "methodname" and the input parameters expected by the web service.
function ExecuteWS()
{
iCallID = service.Calculator.callService("Add",num1.value,num2.value);
}
Our onresult event handler checks the error property to find out if any error occurred in the execution. In case of error, the function displays the details of the error and if successful, the function displays the result from the web service.
The onresult function implementation is shown below.
function onWSresult()
{
if((event.result.error)&&(iCallID==event.result.id))
{
var xfaultcode = event.result.errorDetail.code;
var xfaultstring = event.result.errorDetail.string;
var xfaultsoap = event.result.errorDetail.raw;
document.writeln("ERROR. Method call failed!");
document.writeln("Call ID:" + iCallID);
document.writeln("Fault Code:" + xfaultcode);
document.writeln("Fault String:" + xfaultstring);
document.writeln("SOAP Data:" + xfaultsoap);
}
else if(event.result.error == false)
{
sum.value= event.result.value;
}
}
Here is the complete code listing for the client.
<SCRIPT language="JavaScript">
var iCallID;
function ExecuteWS()
{
iCallID = service.Calculator.callService("Add",num1.value,num2.value);
}
function onWSresult()
{
if((event.result.error)&&(iCallID==event.result.id))
{
var xfaultcode = event.result.errorDetail.code;
var xfaultstring = event.result.errorDetail.string;
var xfaultsoap = event.result.errorDetail.raw;
document.writeln("ERROR. Method call failed!");
document.writeln("Call ID:" + iCallID);
document.writeln("Fault Code:" + xfaultcode);
document.writeln("Fault String:" + xfaultstring);
document.writeln("SOAP Data:" + xfaultsoap);
}
else if(event.result.error == false)
{
sum.value= event.result.value;
}
}
</script>
<body onload= "service.useService('http://localhost/site/code/testws.asmx?WSDL','Calculator');">
<div id="service" style="behavior:url(webservice.htc)" onresult="onWSresult()">
</div>
Number : <input type="text" name='num1'\">
Number : </td><td><input type="text" name='num2'\">
Total:<input type="text" name='sum'\">
<button OnClick="ExecuteWS()">Add Numbers</button>
</body>
Code Listing: Save as test.htm (in a folder containing webservice.htc)
Step 3: Test
Here are the results of our program:
Input screen
Output
If you entered an incorrect integer, for example "xyz" for one of the inputs, the resultant error would be displayed.
Conclusion
This program provides trivial functionality in terms of application processing logic, but it demonstrates a design architecture to access the vast resources and functionality of the .Net Framework. Imagine the possibilities - you could have simple HTML pages invoking complex, shareable logic through simple internet protocols - the client HTML page does not need to be programmed using the .Net framework.