Freitag, Juni 17, 2005

Using WebServices with AJAX Applications

There are still some disadvantages with many available AJAX frameworks on the web and also with my preceding implementation:

  • For each necessary functionality a special page must be realized
  • The url may exceed a length of more than a few 100 chars and will bring up problems.
  • The implementation on the server consists of code fragments used for the communication of parameters and the return value together with the application specific code.

Here it is obvious that using the server side communication infrastructure of webservices brings in some huge advantages:

  • The same functionality can also be used from other webservice enabled applications like Excel.
  • Multiple methods can be implemented together in one class so it is possible to choose the right granularity for bigger collections of webservices.
  • You can use datatypes
  • There is exception handling (more on this later)
  • A proxy can be created for the client that enables an easy implementation of calling a server side method. (more on this soon)
  • The existing SOAP and WSDL standards in the current available version (Spring 2005) are perfect usable on http and https connections. The circumstances for transferring html over http are identical and usable without any problems for webservices. The actual discussions about extending the WebService Infrastructure with security features and routing soap messages are not needed and SOAP is as secure as the web is in this scenario.

WebServices can be implemented very easily in ASP.NET so I prefer this platform in my samples.

The implementation of a WebService for the calculation of the prime factors can be found in CalcService.asmx in ths sample website. The core implementation is the same as in Request.aspx.

<%@ WebService Language="C#" Class="Service" %>

using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;

[WebService(Namespace = "http://www.mathertel.de/CalcFactorsService",
  Description="A WebService for the calculation of prime factors.")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class Service : System.Web.Services.WebService {

  ...
  

  [WebMethod(Description="Calculate all prime factors of a given number.")]
  public string CalcPrimeFactors(string inputText) {
    string outputText = String.Empty;
    UInt64 prime;  // try this factor (only primes will match!)
    UInt64 number; // product of the remaining factors

    if ((inputText == null) || (inputText.Length == 0) || (inputText == "0"))
      return (null);

    prime = 2; // start with 2
    number = UInt64.Parse(inputText);

    while ((number > 1) && (prime * prime <= number)) {
      if (number % prime != 0) {
        // try the next factor (slowly)
        prime += (prime == 2UL ? 1UL : 2UL); 

      } else {
        // found a factor !
        outputText = outputText + " " + prime;
        number = number / prime;
      } // if
    } // while

    if (number > 1) {
      // the last factor (a prime) is here.
      outputText = outputText + " " + number;
    }

    return (outputText);

  } // CalcPrimeFactors

  ...

} // class

see CalcService.asmx on the sample web side.

The special thing here, compared to the previous sample using Request.aspx with a http GET command, is that the functional characteristics of the server side operation gets clear. There is no need for the programmer to care about the details of the communication Because there no usable SOAP client available in the current browsers there is more overhead in the JavaScript programming in the browser for implementing the SOAP protocol as far as we need it. There is in deed a SOAP interface available in Firefox but this implementation is not working correctly and is only partial implemented. Fortunately the assembling of the SOAP request and analyzing the result is also possible with the well known XMLHTTP Object.

// call the server using the SOAP encoding
xmlObj = new ActiveXObject("Microsoft.XMLHTTP");
xmlObj.Open("POST", "http://localhost/CalcFactors/Service.asmx", true);
xmlObj.setRequestHeader("SOAPAction", "http://www.mathertel.de/CalcFactorsService/CalcPrimeFactors");
xmlObj.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
xmlObj.onreadystatechange = RetrievePrimeFactors;
var soapText = "<?xml version='1.0' encoding='utf-8'?>"
  + "<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'>"
  + "<soap:Body>"
    + "<CalcPrimeFactors xmlns='http://www.mathertel.de/CalcFactorsService'>"
      + "<inputText>" + inputText + "</inputText>"
    + "</CalcPrimeFactors>"
  + "</soap:Body>"
+ "</soap:Envelope>";
xmlObj.Send(soapText);

...

// the response is inside the <CalcPrimeFactorsResult> tag
outputText = xmlObj.ResponseText;
p = outputText.indexOf("<CalcPrimeFactorsResult>");
if (p > 0) {
  outputText = outputText.substr(p+24);
  outputText = outputText.substr(0, outputText.indexOf("<"));
} // if

This implementation is only used to show how the SOAP protocol works but has no error handling and lacks of being robust.

This implementation can be found in the page CalcFactorsServerSoap.htm on the sample website. It only works for IE.

The server side code get dramatically simplified when using WebServices. For the client there also exists a good solution.

Stay tuned.

The files for the implementation are available on the sample WebSite