Programmer to ProgrammerTM  
Wrox Press Ltd  
   
  Search ASPToday Living Book ASPToday Living Book
Index Full Text
  cyscape.com

ASPToday Home
 
 
Home HOME
Site Map SITE MAP
Index INDEX
Full-text search SEARCH
Forum FORUM
Feedback FEEDBACK
Advertise with us ADVERTISE
Subscribe SUBSCRIBE
Bullet LOG OFF

                         
      The ASPToday Article
July 28, 2000
      Previous article -
July 27, 2000
  Next article -
July 31, 2000
 
   
   
   
Creating Applications using SOAP and XMLHTTP (Part 2)   Craig Murphy  
by Craig Murphy
 
CATEGORIES:  Scripting, XML/Data Transfer  
ARTICLE TYPE: Overview Reader Comments
   
    ABSTRACT  
 
Article Rating
 
   Useful
  
 46 responses

In my previous article, I discussed the anatomy of a SOAP message, and created an example


application to request information from the server, in a read-only fashion. This article


will deal with the slightly more complicated subject of sending updates back to the


server. We will also see how SOAP allows us to handle errors – or faults in SOAP–speak.




   
                   
    Article Discussion   Rate this article   Related Links   Index Entries  
   
 
    ARTICLE

In my previous article I discussed the anatomy of a SOAP message, and created an example application to request information from the server, in a read-only fashion. This article will deal with the slightly more complicated subject of sending updates back to the server. We will also see how SOAP allows us to handle errors – or faults in SOAP–speak.

During July 2000 Microsoft announced Microsoft.NET (http://www.microsoft.com/presspass/features/2000/jul00/07-11.netframework.asp?WROXEMPTOKEN=518350ZSBpx5gK3ak3hXhNoMOk). Part of that announcement explained the technologies and protocols that would be used, namely: SOAP and XML. In the same month, the BizTalk Framework 2.0 (draft) was released. Not surprisingly, that too will take advantage of XML–based messaging using SOAP and HTTP as the initial transport mechanism. Clearly Microsoft believes that there is some mileage there, even if SOAP is still a maturing protocol that will only succeed with adoption and use. The material presented over the course of these articles should provide you with enough material to get your first SOAP–based application off the ground.

Whilst BizTalk (http://www.microsoft.com/biztalk?WROXEMPTOKEN=518350ZSBpx5gK3ak3hXhNoMOk) uses SOAP, XML, and HTTP it’s beyond the scope of this article.

Re-cap

Our example application contains the Employee Details input form shown below. The full application is available as part of the download. If you’ve not already done so, you’ll need to create a DSN called ASPToday and point it at the sample database. I would suggest that you extract the files into a directory called asptoday off the web server root.

An Update button has been added:

The HTML controls have been modified to handle key presses – so we can record any updates.

<input type="text" name="emp_no" size="8" disabled="true">
<input type="text" name="last_name" size="24" onkeyup="cell_change(this)">
<input type="text" name="first_name" size="24" onkeyup="cell_change(this)">
etc.

Whenever the user types into the HTML control, the function cell_change is called – more on this shortly.

Any changes that are made to the employee details will enable the Update button. The Update button sends another SOAP request to the server that contains the new employee details.

Sending updates back to the server

Each time a new employee is selected, a JavaScript object g_employee is populated with the new employee details. We saw g_employee being set in the refclick() function:

// Send a SOAP request to get the selected employee details...
g_employee = cmSOAP( 'getEmployeeDetail', 
                     cbUseXML.checked ? cmSOAPrtXMLDOM:cmSOAPrtObject, 
                     'emp_no', sEmpNo);

Our HTML controls use the same name as the XML elements that are returned from the database. This allows us to write a generic JavaScript function to handle updating the JavaScript object. So, using the code snippet below, we can see how the g_employee object contains properties whose names match the HTML controls:

with (g_employee) {
  car_reg.value     = employee.car_reg;
  car_maker.value   = employee.car_maker;
  car_model.value   = employee.car_model;
  base_office.value = employee.base_office;
  last_name.value   = employee.last_name;
  first_name.value  = employee.first_name;
}

Each time the user changes an HTML control, we need to make some changes to the employee object. The HTML controls have been modified to call some client–side JavaScript each time a key is pressed:

<input type="text" name="last_name" size="24" onkeyup="cell_change(this)">

function cell_change(obj) {
  var s='';
  btn_update.disabled=false;
  s='g_employee.employee.' + obj.name + '="' + obj.value +'"';
  eval(s);
}

Using this technique, we could easily reduce network traffic by only sending the employee detail fields that have changed. If you have a large record, this might be an approach for you to consider.

We’ve already seen how to convert XML into a JavaScript object, now we need to take an updated JavaScript object and convert it into XML. Here’s a function to do just that:

function ObjectToXML(root,obj)
{
  var s='<' + root + '>';
  for (key in obj)
  {
     s += '<' + key + '>' + obj[key] + '</' + key + '>';
  }
  s +='</' + root + '>';

  return s;
}

The syntax is easy: ObjectToXML('employee', g_employee.employee); . This will create a string that contains all the properties and values in the JavaScript object g_employee.employee , bounded by <employee> and </employee> tags.

So, given this JavaScript object:

g_employee.employee.last_name = "Murphy";
g_employee.employee.first_name = "Craig";

A call to ObjectToXML('employee', g_employee.employee); creates a string looks like this:

<employee><last_name>Murphy</last_name><first_name>Craig</first_name></employee>

Now that we can update our employee object, it’s an easy task getting it back to the server. The code required to send the update back to the server is:

update_response = cmSOAP( 'putEmployeeDetail', cmSOAPrtXMLDOM, 
                          ObjectToXML('employee', g_employee.employee));

The call to cmSOAP(…) creates a SOAP Request which is then sent to the SOAP Listener. The SOAP Request resembles:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope">
<SOAP-ENV:Body>

<m:putEmployeeDetail xmlns:m="http://www.craigmurphy.com/hrweb">
<employee>
<emp_no>5</emp_no>
<last_name>Butcher</last_name>
<first_name>Frank</first_name>
<base_office>Walford</base_office>
<car_reg>EAST 1</car_reg>
<car_model>XJS</car_model>
<car_maker>Jaguar</car_maker>
</employee>
</m:putEmployeeDetail>

</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

The SOAP Listener that we used to identify the SOAP method has to be updated to handle the new putEmployeeDetail method – here’s the JavaScript that we require:

var SOAPEnvelope = Server.CreateObject("Microsoft.XMLDOM");

// Load the SOAP envelope
SOAPEnvelope.async = false;
SOAPEnvelope.load (Request);

Response.ContentType="text/xml";

// Extract the method
var smn = new String(Request.ServerVariables("HTTP_SOAPACTION")); 
var sSOAPActionMethod = smn.substring(smn.lastIndexOf("#") + 1, smn.length);

var oBody   = SOAPEnvelope.selectSingleNode("//SOAP-ENV:Body");
var oMethod = oBody.firstChild;
var sMethod = oMethod.baseName;

// Which method?
if (sSOAPActionMethod == sMethod)
  switch (sMethod) {
    case "getEmployeeDetail":
      var nodeEmpNo = oBody.selectSingleNode("//emp_no");
      var sEmpNo    = nodeEmpNo.text;
      var re        = getEmployeeDetail(sEmpNo);
      Response.Write(re);  
      break;   

    case "putEmployeeDetail":
      var obj = cmXMLToObject(oMethod);
      var re = putEmployeeDetail(obj.employee.emp_no, obj);
      Response.Write(re);
      break;

      default: 
      //method is undefined
  }

oMethod holds the actual SOAP method payload:

<m:putEmployeeDetail xmlns:m="http://www.craigmurphy.com/hrweb">
<employee>
<emp_no>5</emp_no>
<last_name>Butcher</last_name>
<first_name>Frank</first_name>
<base_office>Walford</base_office>
<car_reg>EAST 1</car_reg>
<car_model>XJS</car_model>
<car_maker>Jaguar</car_maker>
</employee>
</m:putEmployeeDetail>

By calling cmXMLToObject(oMethod); we are able to convert the SOAP payload into a JavaScript object. Yes – we did convert XML into a JavaScript object on the client, then converted the object back into XML before transmitting to the server! Thus our update function can access the edited elements using the following code:

// Update the given employee details based on the contents of obj
function putEmployeeDetail(sEmpNo, obj) {
var Source;
var Connect;
var oRS;

Source = "SELECT * FROM tblEmployees WHERE emp_no=" + sEmpNo;
Connect = "DSN=ASPToday;UID=;PWD=;";

var oRS = Server.CreateObject("ADODB.RecordSet");
oRS.open(Source, Connect, adOpenDynamic, adLockOptimistic);

with (obj.employee) {
  oRS("emp_last_name")   = last_name;
  oRS("emp_first_name")  = first_name;
  oRS("emp_office")      = base_office;
  oRS("emp_car_reg")     = car_reg;
  oRS("emp_car_model")   = car_model;
  oRS("emp_car_maker")   = car_maker;
}

oRS.Update();

When all around you collapses…

As developers, we would be naïve to think that everything will work perfectly all of the time. SOAP allows the server method being executed an opportunity to indicate success or not as the case may be. If the response is successful, then client can continue without further checking. However, if the response indicates failure or some other fault, the client may have to take alternative measures.

It’s likely that you’ll need to indicate failure to your client application – for any number of reasons. The client application might:

Whereas the server may encounter problems that prevent it honoring the SOAP Request:

An unsuccessful SOAP Request results in a SOAP Response that contains a Fault element.

A Fault element can only appear once, and it is compulsory that it appears as a child of the Body element, i.e. it must appear inside the Body element.

Here is a sample SOAP Request that contains a Fault element:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Server</faultcode>
<faultstring>Database Error</faultstring>
<detail>
<err:hrweb xmlns:err="http://www.craigmurphy.com/hrweb/errors">
<description>Employee 549 in table tblEmployee does not exist</description> 
<errorcode>0001E</errorcode> 
</err:hrweb> 
</detail> 
</SOAP-ENV:Fault> 
</SOAP-ENV:Body> 
</SOAP-ENV:Envelope> 

The Fault element comprises of a faultcode , a faultstring and the detail of the fault. There’s also the notion of a faultactor – we can think of the faultactor as being the ASP script that actually processes the SOAP message, in this can cmSOAPListener.asp . If the original SOAP Request cannot be processed, then a detail element is compulsory.

Faultcodes

Faultcodes have their origin in HTTP server status codes – these are essentially integers, you’ve probably seen a 404 Not Found error in your browser at some point.

However, despite being "based" on HTTP server codes, I can’t recommend setting Response.status = 4xx in your SOAP Listener. It’s important to note that the HTTP server status codes are there for a reason – and we should not be interfering with them. We should also remember that not all SOAP implementations will use HTTP, and thus will not have access to the Response.status property. You’ll find there is a great debate about SOAP Fault handling at the DevelopMentor discussion list.

The SOAP specification suggests four top–level faultcodes:

Rather than return numeric faultcodes, SOAP allows us to return something that’s a little more readable from a human point of view – but equally as readable mechanically (i.e. by the client application).

Thus, to specify a faultcode, we would provide a top–level faultcode as a prefix followed by a descriptive postfix (separating the prefix and postfix with a period), e.g. Server.Timeout , Client.BadRequest . The SOAP specification doesn’t define an exhaustive list of postfix descriptions, e.g. Timeout , BadRequest etc. Essentially, we can treat the postfix as being application-specific – this means that we can freely define our own faultcodes as time goes by.

The faultcode is compulsory and should be prefixed with a namespace, e.g.

<faultcode>SOAP-ENV:Server</faultcode>

Server Faultcodes

Server faultcodes represent errors related to the server infrastructure. The SOAP Request is syntactically correct and is considered to be a valid request – however the server cannot process it "at this time". If the client resends the SOAP Request it may succeed.

A sample server faultcode might be:

<faultcode>SOAP-ENV:Server.Unavailable</faultcode>

Client Faultcodes

Client faultcodes represent errors related to the SOAP Request. The client application may have submitted a request that is malformed, or otherwise syntactically incorrect. Equally, the client may have correctly specified a method, but failed to provide the parameters required to execute the method.

A sample client faultcode might be:

<faultcode>SOAP-ENV:Client.UnknownMethod</faultcode>

MustUnderstand Faultcodes

To date, the SOAP messages that we have seen consisted only of a Body element – the optional Header element has not been required. The Header element can be used to provide additional information related to the SOAP Body. For example, we could choose to include a "user name" in the header – whilst it doesn’t affect the meaning of the SOAP message, it is may help us implement an audit log.

If we added a Header element to our SOAP messages, we can use the mustUnderstand attribute to indicate whether the SOAP Listener (or final endpoint) can choose to ignore the Header. If the mustUnderstand attribute is set to "1" then the Header must be processed.

By default, if there is a Header element without a mustUnderstand attribute, the SOAP Listener (or final endpoint) may assume that mustUnderstand is "0", i.e. it may ignore the Header.

Here’s an example of a Header element depicting a UserName :

<SOAP-ENV:Header>
<u:UserName xmlns:t="http://craigmurphy.com/users" SOAP-ENV:mustUnderstand="1">CraigM
</u:UserName>
</SOAP-ENV:Header>

VersionMismatch Faultcodes

The SOAP messages that we have seen to date used the SOAP-ENV prefix and a namespace of http://schemas.xmlsoap.org/soap/envelope?WROXEMPTOKEN=518350ZSBpx5gK3ak3hXhNoMOk. If the server (SOAP listener) receives a SOAP message where the SOAP Envelope namespace is different, then a VersionMismatch faultcode is generated. Ultimately, the SOAP message is ignored.


Faultstrings

Faultstrings are compulsory and are used to provide a summary of the fault – something that is suitable for human consumption.

<faultstring>Database Error</faultstring>

Faultactors

Faultactors are optional, but if you include them, they should indicate which endpoint actually raised the fault. In our case, there is only one endpoint: cmSOAPListener.asp .

<faultactor>cmSOAPListener.asp</faultactor>

So that’s the theory behind SOAP faults covered – let’s take a look at how we could implement them.

We can use a JavaScript function to build a suitably formatted SOAP fault:

// Prepare a SOAP Fault, based on the parameters that are passed in
function cmSOAPFault(faultcode, faultstring, faultactor, desc, errcode)
{
  var s=  '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">';
  s = s + '<SOAP-ENV:Body>';
  s = s + '<SOAP-ENV:Fault>';
  s = s + '<faultcode>SOAP-ENV:' + faultcode + '</faultcode>';
  s = s + '<faultstring>' + faultstring + '</faultstring>';
  s = s + '<faultactor>' + faultactor + '</faultactor>';
  s = s + '<detail>';
  s = s + '<err:hrweb xmlns:err="' + cmSOAPErrorURI + '">';
  s = s + '<description>';
  s = s + desc
  s = s + '</description>';
  s = s + '<errorcode>';
  s = s + errcode
  s = s + '</errorcode>';
  s = s + '</err:hrweb>';
  s = s + '</detail>';
  s = s + '</SOAP-ENV:Fault>';
  s = s + '</SOAP-ENV:Body>';
  s = s + '</SOAP-ENV:Envelope>';

  return s;
}

We can now apply this function in our putEmployeeDetail method – the code below now checks that the employee record actually exists before the update takes place:

// Update the given employee details based on the contents of obj
function putEmployeeDetail(sEmpNo, obj) {
var Source;
var Connect;
var oRS;
   
Source = "SELECT * FROM tblEmployees WHERE emp_no=" + sEmpNo;
Connect = "DSN=ASPToday;UID=;PWD=;";

var oRS = Server.CreateObject("ADODB.RecordSet");
oRS.open(Source, Connect, adOpenDynamic, adLockOptimistic);

// did we get an employee record?
if ((oRS.EOF) && (oRS.BOF)) {
   // No, we got nothing back...raise a fault

  r = cmSOAPFault(  300,
         'Record Not Found', 
         'cmSOAPListener.asp#putEmployeeDetail',
         sEmpNo + ' was not found in tblEmployees',
         1001);
}
else
{
   // yes, we did get an employee record, so let's update it
  with (obj.employee) {
      oRS("emp_last_name")   = last_name;
      oRS("emp_first_name")  = first_name;
      oRS("emp_office")      = base_office;
      oRS("emp_car_reg")     = car_reg;
      oRS("emp_car_model")   = car_model;
      oRS("emp_car_maker")   = car_maker;
   }

   oRS.Update();
   r = cmSOAPResponse('putEmployeeDetail', '<ReturnCode>Success</ReturnCode>');
}


oRS.Close();

return r;
}

To make life a little easier, I’ve included a checkbox on the HTML page:

By checking this box, we can induce an error, – employee not found to be exact. This will allow us to see an update failure. Although I don’t deal with the error, I do warn the user by presenting each of the fault elements.

When a faultcode is delivered to the client, the following code allows us to extract the fault description and display an error.

update_response = cmSOAP('putEmployeeDetail', 
                         cmSOAPrtXMLDOM, 
                         ObjectToXML('employee', g_employee.employee));

// Was there a fault?
if (update_response.baseName == "Fault") {
  // Yes, show the user the full fault description...
  var sErr = "Faultcode: "  + update_response.selectSingleNode("faultcode").text;
      sErr = sErr + "\nfaultstring: "+ update_response.selectSingleNode("faultstring").text;
      sErr = sErr + "\nfaultactor: " + update_response.selectSingleNode("faultactor").text;
      sErr = sErr + "\ndetail: "     + update_response.selectSingleNode("detail/err:hrweb/description").text;
      sErr = sErr + "\nerror code: " + update_response.selectSingleNode("detail/err:hrweb/errorcode").text;
      alert(sErr);
}
else
{ 
  // No, everything's fine, update the employee list with the new values...
  source.async=false;
  source.load("employees.asp");
  xslTarget.innerHTML = source.transformNode(style.XMLDocument);
  window.status="";
  btn_update.disabled=true;
  btn_update_clsid.disabled=true;
}

That’s all we’re going to see regarding fault codes. Many SOAP faults will be specific to your application, so I have provided just enough source code for you to start creating and handling faults.

We’ll now see how a COM component can help us build our SOAP solutions.

Executing methods within a COM component

We have seen that the body of a SOAP message is XML. The method name is embodied within the SOAP Request Body, and is also passed to the server via an HTTP header ( SOAPAction ). This works well, however, we are not limited to passing the method name – we can pass a CLSID instead. Thus a request might look like:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope">
<SOAP-ENV:Body>
<m:getEmployeeDetail xmlns:m="uuid:74B92E80-5917-11d4-B50F-0050DAD176A3">
<emp_no>1302</emp_no>
</m:getEmployeeDetail>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

The corresponding SOAPAction might look like this:

SOAPAction: uuid:74B92E80-5917-11d4-B50F-0050DAD176A3#putEmployeeDetail

This can be interpreted as meaning: "invoke the putEmployeeDetail method using the component associated with the given CLSID". Thus, you can give your SOAP applications the power of executing pre–compiled method that are embodied within a COM server/component. It’s perfectly possible that a Macintosh user can interact with an application (and execute methods!) running under NT.

To demonstrate this, we’ll create a Windows Script Component (WSC) that allows us to perform the same employee update we used earlier. Whilst we’re not going to get any performance benefits, the script is still interpreted, so it allows us to "prototype" our COM methods. It’s also easier to debug WSCs. If performance became an issue, re–building the WSC methods in your favorite compiled language (Visual Basic, Visual C++, Delphi, etc.) is a relatively painless process.

Here’s the source code for this component – update.wsc :

<?xml version="1.0"?>
<component>

<registration
   description="putEmployeeDetail"
   progid="HRWeb.Update"
   version="1.00"
   classid="{74B92E80-5917-11d4-B50F-0050DAD176A3}"
>
</registration>

<public>
   <method name="putEmployeeDetail">
      <parameter name="sEmpNo" />
      <parameter name="obj" />
   </method>
</public>

<implements type="ASP" id="ASP"/>

<script language="JScript">
<![CDATA[

// Update the given employee details based on the contents of obj
function putEmployeeDetail(sEmpNo, obj) {
   var Source;
   var Connect;
   var oRS;

   Source = "SELECT * FROM tblEmployees WHERE emp_no=" + sEmpNo;
   Connect = "DSN=ASPToday;UID=;PWD=;";

   var oRS = Server.CreateObject("ADODB.RecordSet");
   oRS.open(Source, Connect, adOpenDynamic, adLockOptimistic);

   with (obj.employee) {
    oRS("emp_last_name")   = last_name;
    oRS("emp_first_name")  = first_name;
    oRS("emp_office")      = base_office;
    oRS("emp_car_reg")     = car_reg;
    oRS("emp_car_model")   = car_model;
    oRS("emp_car_maker")   = car_maker;
  }

  oRS.Update();

  r='<?xml version="1.0"?>';
  r=r+'<putEmployeeDetail>';
  r=r+'<ReturnCode>Success</ReturnCode>';
  r=r+'</putEmployeeDetail>';
  
  oRS.Close();

  return r;
}

]]>
</script>

</component>

You’ll need to register the WSC (on the same machine as the web server) – this can easily be done by right–clicking on the update.wsc file, then by clicking on the register menu option:

I’ve already mentioned that WSCs are interpreted. This means that we don’t have to Unregister and re– Register the component after we’ve made changes to it.

When the server receives the SOAP message it need to create an instance of the class, set up any parameters, then execute the method. I’ve modified the SOAP Listener to demonstrate handling SOAP Requests that use a COM component. The salient changes in cmSOAPCOMListener.asp are shown below:

// Which method?
if (sSOAPActionMethod == sMethod)
switch (sMethod) {  

  case "putEmployeeDetail":
    var clsid = oMethod.namespaceURI.substr(oMethod.namespaceURI.indexOf( ":")+1);

    ProgID = ProgIDFromCLSID(clsid);

    var COMObj = Server.CreateObject(ProgID);

    var obj = cmXMLToObject(oMethod);

    var re = COMObj.putEmployeeDetail(obj.employee.emp_no, obj);

    Response.Write(re);
    break;

  default: 
   // method is undefined
}

Given that we know oMethod holds this value: <m:getEmployeeDetail xmlns:m="uuid: 74B92E80-5917-11d4-B50F-0050DAD176A3"> , the first thing we do is extract the CLSID:

var clsid=oMethod.namespaceURI.substr(oMethod.namespaceURI.indexOf(":")+1);

The namespaceURI property of oMethod (an XML node), holds the value: uuid: 74B92E80-5917-11d4-B50F-0050DAD176A3. After we’ve stripped off the leading uuid: , we have a CLSID that can be instantiated.

I’ve also added another button to the HTML form, Update using CLSID . The onClick event uses the SOAPCOMListener.asp as the endpoint:

The code behind the button Update using CLSID is fairly similar to the original code:

update_response = cmSOAP_COM('uuid:74B92E80-5917-11d4-B50F-0050DAD176A3',
                  'putEmployeeDetail', 
                  cmSOAPrtXML, 
                  ObjectToXML('employee', g_employee.employee));

That’s all there is to it. You can safely use the CLSID provided here, I created it on a machine with a network card.

Summary

Over the course of these two articles we’ve looked at SOAP from an implementation aspect. By working through a small example application I hope that you’ve got a better understanding of what SOAP is and what it can do for your web development. In particular, we covered the following:

I have found that by writing a lot of my code using a true "black box" approach, I am able to offer my methods to colleagues (in the same office and elsewhere in the organization). SOAP has helped promote the notion of a "single source of data" – no longer do we need to have "pockets or islands of data" stuck in multiple desktop databases. By moving those databases onto a web server with some SOAP methods for access and update, we are able to bring disparate (and remote) systems closer together.

However, if SOAP is to succeed, there will need to be global means of surfacing SOAP methods from our websites. For example, how do you know that www.weatherwise.com offers methods for getting your local weather? Equally, how do you know what the SOAP Listener is called (if one exists)? There needs to be some form of "web service discovery". Microsoft has proposed the Service Description Language (SDL), which is a means of describing the methods that are published via HTTP or SMTP. The SDL, like SOAP, doesn’t assume that HTTP will be used as the transport mechanism. Whilst SDL is embryonic, it opens the door to a truly global web service–oriented environment, with shared processing, supply–chain alliances, and feature rich web-pages/applications.

 
 
   
  RATE THIS ARTICLE
  Please rate this article (1-5). Was this article...
 
 
Useful? No Yes, Very
 
Innovative? No Yes, Very
 
Informative? No Yes, Very
 
Brief Reader Comments?
Your Name:
(Optional)
 
  USEFUL LINKS
  Related Tasks:
 
 
   
  Related ASPToday Articles
   
  • Creating applications using SOAP and XMLHTTP Part 3 (August 21, 2000)
  • Creating applications using SOAP and XMLHTTP Part 1 (July 18, 2000)
  • Monitor Your Web Site Performance with the XMLHTTP Component Part 1 (June 6, 2000)
  •  
           
     
     
      Related Sources
     
  • SOAP Discussion at DevelopMentor: http://discuss.develop.com/archives/wa.exe?A2=ind0006&L=soap&F=&S=&P=32893
  • BizTalk: http://www.microsoft.com/biztalk/
  • Microsoft.NET announcement: http://www.microsoft.com/presspass/features/2000/jul00/07-11.netframework.asp
  •  
     
           
      Search the ASPToday Living Book   ASPToday Living Book
     
      Index Full Text Advanced 
     
     
           
      Index Entries in this Article
     
  • client faultcodes
  •  
  • COM components
  •  
  • COM components, methods executing within
  •  
  • error handling
  •  
  • Fault element
  •  
  • faultactors
  •  
  • faultcodes
  •  
  • faultstrings
  •  
  • JavaScript
  •  
  • mustUnderstand faultcodes
  •  
  • sending updates to server
  •  
  • server faultcodes
  •  
  • SOAP
  •  
  • SOAP Listener
  •  
  • SOAP Requests
  •  
  • SOAP Responses
  •  
  • VersionMismatch faultcodes
  •  
  • Windows Script Components
  •  
  • WSC
  •  
     
     
    HOME | SITE MAP | INDEX | SEARCH | REFERENCE | FEEDBACK | ADVERTISE | SUBSCRIBE
    .NET Framework Components Data Access DNA 2000 E-commerce Performance
    Security Admin Site Design Scripting XML/Data Transfer Other Technologies

     
    ASPToday is brought to you by Wrox Press (http://www.asptoday.com/OffSiteRedirect.asp?Advertiser=www.wrox.com/&WROXEMPTOKEN=518350ZSBpx5gK3ak3hXhNoMOk). Please see our terms and conditions and privacy policy.
    ASPToday is optimised for Microsoft Internet Explorer 5 browsers.
    Please report any website problems to webmaster@asptoday.com. Copyright © 2002 Wrox Press. All Rights Reserved.