Login | Register   
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

Synchronize Your Databases with .NET Web Services (Part I) : Page 7

The ever-increasing use of XML is an exciting development in Web site design and construction, and provides new ways for site authors to expose information to visitors. In this two-part article, you'll see how to create a data-driven Web service and explore three different ways to consume it. Then, in part II, you'll see how to use such services to synchronize the content in distributed databases automatically.


advertisement
Accessing a Web Service with the IE5 Web Service Behavior
The ASP.NET example provides a neat and simple solution to consuming a Web service, though it only works because ASP.NET understands the objects we've used—an ASP.NET Web service and a .NET DataSet. Other clients may not have the same level of support for .NET objects, but that doesn't mean they can't be persuaded to use a Web service.

For example, Internet Explorer has no concept of.NET, and the scripting languages it provides (VBScript and JScript) are not managed code languages. However, IE (version 5 and higher) can take advantage of a script behavior (a HyperText Component or HTC) that you can use to interact with a Web service from client-side script.

You can find more information and download the IE5 Web service behavior here. You place the behavior file (which is named webservice.htc) on your Web server and the client then fetches it when required.

The ie5-client.aspx page (in the ie5-client folder) demonstrates the use of this Web service behavior. You insert the behavior component into a page using the standard approach for HTCs, by defining it in a style attribute of an element using the special behaviour:url() selector. The example page attaches the behavior to the <span> element that contains the page heading:

<span class="heading" id="htcWService" style="behavior:url(webservice.htc)"> Accessing a Web service using the IE5 Web service Behavior </span><hr />

The remainder of the visible part of the page consists of a couple of text boxes for the week and year values, and a "submit" button that runs the client-side code (as the button is not within a <form> it will not cause a postback when clicked). There's also a <span> element that shows interactive status messages, and a <div> to display the results:

Starting from week: <input type="text" size="1" value="4" name="txtWeek" /> year: <input type="text" size="4" value="2004" name="txtYear" /> <input type="submit" value="Go" onclick="openWebService()" /> <p /> <span id="lblStatus"></span><p /> <div id="divResult"></div>

The code required to use the Web service behavior is not complex, but can become quite lengthy if you choose to handle errors properly. It also makes sense to load the results of the Web service method call asynchronously, so that the page can continue to operate (and display status details) as the Web service is located and accessed—which also requires additional code.

Basically, you start by calling the useService method of the component to establish the connection to the Web service. This downloads the WSDL service definition (you can see that "?WSDL" is appended to the URL as a query string), and establishes a "friendly name" used to refer to the Web service later in the code.



htcWService.useService( "../webservices/trafficparameters.asmx?WSDL", "TrafficData");

After this, you can call the method(s) of the Web service using the "TrafficData" friendly name. The following code collects the week and year values from the text boxes on the page, and uses those as parameters to call the TrafficSummaryFromWeekYear method:

var sWeek = document.all['txtWeek'].value; var sYear = document.all['txtYear'].value; var iCallID = htcWService.TrafficData.callService(dataLoaded, "TrafficSummaryFromWeekYear", sWeek, sYear);

The first parameter to the callService method shown in the last line of the preceding code is the name of a delegate or event handler to execute when the component has finished downloading the SOAP message returned by the Web service. The next listing shows that dataLoaded delegate function. It first checks for an error, and if all is well, creates a new instance of the MSXML parser provided with IE5 (the code uses the free-threaded version because it has to perform an XSLT transformation on the content later for display):

function dataLoaded(oResult) { if(oResult.error) { // ... display error details ... } else { oXMLData = new ActiveXObject( 'MSXML2.FreeThreadedDOMDocument'); oXMLData.onreadystatechange = changeFunction; oXMLData.validateOnParse = true; oXMLData.async = true; oXMLData.loadXML(oResult.raw.xml); } }

Again, the code uses asynchronous loading, this time by specifying the delegate named changeFunction to be executed each time the readystate property of the MSXML parser changes. Now you can start loading the parser with the XML document that lies within the SOAP envelope that the Web service behavior received from the Web service. The Web service behavior passes a "result" object to this callback function. You get at the "content" by accessing the raw.xml property of the result object. This XML document is, of course, the diffgram that represents the .NET DataSet.

As the MSXML parser initializes, extracts the XML document from the SOAP package, loads it, parses it and validates it, the readystate property of the parser changes at each stage, so the changeFunction method gets called repeatedly. It's only when the readystate property reaches the value 4 that the process is complete. At this point you can check for an error, and if everything succeeded, call another routine that will display the XML document:

function changeFunction() { if (oXMLData.readyState == 4) { if (oXMLData.parseError.errorCode != 0) // ... display error details ... else { showData(); } } }

The problem is that IE5 doesn't know what a DataSet is and so you can't use techniques such as data binding to display it. As far as IE5 is concerned, the Web service return value is just an XML document with an inline schema, loaded into an instance of the MSXML parser. Fortunately, that means you can use any technique that works with XML documents to process the content.

The ShowData routine uses a simple XSLT stylesheet to transform the XML document into an HTML table for display. The transformation process loads the stylesheet into another instance of MSXML (you must use the free-threaded version for this approach to work), creates s XSLTemplate and Processor instances, and performs the transformation to return a string. The string is then inserted into the <div> element on the page:

function showData() { // create a new parser object instance and load stylesheet var oXMLStyle = new ActiveXObject( 'MSXML2.FreeThreadedDOMDocument'); oXMLStyle.async = false; oXMLStyle.load('style-dataset.xsl'); if (oXMLStyle.parseError.errorCode != 0) { // ... display error message ... return; } // create a new XSLTemplate object and set stylesheet var oTemplate = new ActiveXObject('MSXML2.XSLTemplate'); oTemplate.stylesheet = oXMLStyle; // create a processor and specify the XML parser to use var oProc = oTemplate.createProcessor(); oProc.input = oXMLData; // perform transformation and display results in the page if (oProc.transform() == true) divResult.innerHTML = oProc.output; else // ... display error message ... } //--> </script>

The result of the process is shown in Figure 6. You can see that the results are much the same as you get when accessing the Web service through a .NET proxy in an ASP.NET page, although the grid formatting is less garish in this example.



Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.