soap.lzx
<library>
<include href="rpc/rpc.lzx"/>
<include href="rpc/library/soap.js"/>
<class name="soap" extends="rpc">
<attribute name="wsdl" type="string"/>
<attribute name="service" value="
" type="string"/>
<attribute name="port" value="
" type="string"/>
<attribute name="requestheaders" value="null
" type="expression"/>
<attribute name="responseheaders" value="null
" type="expression"/>
<attribute name="proto" value="null
" type="expression"/>
<method name="load">
LzSOAPService.loadObject(this._loadDel,
{ wsdl: this.wsdl, service: this.service, port: this.port },
this.secure, this.secureport);
</method>
<method name="init">
if (canvas.runtime == "dhtml") {
Debug.warn("SOAP RPC only partially implemented in the DHTML runtime.");
}
if (this['wsdl'] == null) {
Debug.write('soap error: required wsdl attribute not set');
return;
}
super.init();
</method>
<method name="_setup" args="o">
var ok = super._setup(o);
if (ok) {
var stubinfo = o.stubinfo;
this.service = o.stubinfo.service;
this.port = o.stubinfo.port;
if ( o.stubinfo['proto'] ) {
this.proto = o.stubinfo.proto;
}
for (var k in this.proxy) {
var tpka = this.proxy[k]['args'];
if (tpka == null) {
tpka = this.proxy[k].args = {};
}
tpka.superclass = this;
}
}
return ok;
</method>
<method name="makeProxyStubFunction" args="fn">
var stubinfo = this.proxyinfo[fn];
//"Multiply": function ()
//{var args = arguments.callee.args;
// return LzSOAPService.invoke(arguments[1],
// arguments[0],
// args.superclass.requestheaders,
// {"parts": [["tns:Multiply",
// null]],
// "opstyle": "document",
// "operation": "Multiply",
// "port": "MathServiceSoap",
// "service": "MathService",
// "wsdl": "http://www.dotnetjunkies.com/quickstart/aspplus......./mathservice.asmx?WSDL"},
// args.superclass.secure,
var stubfunc = function (){
var args = arguments.callee.args;
return LzSOAPService.invoke(
arguments[1],
arguments[0],
args.superclass.requestheaders,
stubinfo, false, null);
}
return stubfunc;
</method>
<doc>
<tag name="shortdesc"><text>SOAP (Simple Object Access Prototcol)</text></tag>
<text>
<p>SOAP (Simple Object Access Prototcol) is used to exchange information in a
distributed environment. A typical scenarion involves a SOAP client invoking a
client-side function stub to invoke a SOAP web service operation. The SOAP web
service then returns data to the client, like stock information or the result to
a math function. The <a href="http://www.w3.org/TR/soap/" shape="rect">SOAP
protocol</a> is a work in progress being drafted by the <a href="http://www.w3.org" shape="rect">W3C</a>. For the latest SOAP
information.</p>
<p>The <soap> element creates a client-side representation of a SOAP
service based on a WSDL. The name and wsdl attributes are required.</p>
<example>
<canvas debug="true" height="530">
<debug x="15" y="15" width="415" height="500" />
<soap name="amazon"
wsdl="http://soap.amazon.com/schemas3/AmazonWebServices.wsdl">
<handler name="onload">
Debug.debug('Amazon soap service loaded');
Debug.debug('Compare proxy stubs with WSDL SOAP operations.');
Debug.debug('Amazon WSDL at %w', this.wsdl);
Debug.debug('proxy:');
Debug.inspect(this.proxy);
</handler>
<handler name="onerror" args="error">
Debug.debug('error: %w', error);
</handler>
</soap>
</canvas>
</example>
<p>Document style operations use XML (i.e. documents) as paramaters. Document
style operations return an array of <sgmltag class="element" role="LzDataElement">LzDataElement</sgmltag>s,
though often only a single
<code class="classname">LzDataElement</code> will exist in the array. The XML string (document) parameter
passed into the operation must match the XML schema as defined in the WSDL.</p>
<example>
<canvas debug="true">
<debug y="30" x="145" width="350" height="300" />
<!-- This SOAP service uses document/literal messages for its
operations. Each operation is passed a document as a parameter. -->
<soap name="maths"
wsdl="http://www.dotnetjunkies.com/quickstart/aspplus/samples/services/MathService/VB/MathService.asmx?WSDL">
<!-- Method to make a document for SOAP message requests -->
<method name="makedoc" args="func, av, bv">
<![CDATA[
if (func == null) return;
var s = '<' + func + ' xmlns="' + 'http://tempuri.org/' + '" >' +
'<A>' + av + '</A>' +
'<B>' + bv + '</B>' +
'</' + func + '>';
Debug.debug("%w", s);
return s;
]]>
</method>
<handler name="onload">
// make buttons visible once SOAP object is loaded
canvas.buttons.setAttribute('visible', true);
</handler>
<handler name="onerror" args="error">
Debug.debug('error: %w', error);
</handler>
<handler name="ontimeout" args="error">
Debug.debug('timeout: %w', error);
</handler>
<handler name="ondata" args="value">
Debug.debug("%w", value);
result.setAttribute('text', value);
</handler>
<remotecall funcname="Add">
<param value="${ canvas.maths.makedoc(parent.name, a.text, b.text) }" />
</remotecall>
<remotecall funcname="Subtract">
<param value="${ canvas.maths.makedoc(parent.name, a.text, b.text) }" />
</remotecall>
<remotecall funcname="Multiply">
<param value="${ canvas.maths.makedoc(parent.name, a.text, b.text) }" />
</remotecall>
<remotecall funcname="Divide">
<param value="${ canvas.maths.makedoc(parent.name, a.text, b.text) }" />
</remotecall>
</soap>
<view name="buttons" x="10" y="10" visible="false" layout="spacing: 10" >
<text><b>.NET MathService</b></text>
<view layout="axis: x" ><text y="3">a:</text><edittext id="a" text="10"/></view>
<view layout="axis: x" ><text y="3">b:</text><edittext id="b" text="2" /></view>
<view layout="axis: x" ><text>result:</text><text id="result"/></view>
<button text="add" onclick="canvas.maths.Add.invoke()" />
<button text="subtract" onclick="canvas.maths.Subtract.invoke()" />
<button text="multiply" onclick="canvas.maths.Multiply.invoke()" />
<button text="divide" onclick="canvas.maths.Divide.invoke()" />
</view>
</canvas>
</example>
<p>The XML Schema in the WSDL describes how the XML should be structured for
each of the operations. The WSDL below describes how what the schema should look
like for the <code>Add</code> operation.</p>
<programlisting>
<definitions xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:s="http://www.w3.org/2001/XMLSchema"
xmlns:s0="http://tempuri.org/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/"
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
targetNamespace="http://tempuri.org/"
xmlns="http://schemas.xmlsoap.org/wsdl/">
<types>
<s:schema elementFormDefault="qualified" targetNamespace="http://tempuri.org/">
<s:element name="Add">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="A" type="s:float" />
<s:element minOccurs="1" maxOccurs="1" name="B" type="s:float" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="AddResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="AddResult" type="s:float" />
</s:sequence>
</s:complexType>
</s:element>
<!-- MORE SCHEMA DECLARATION (for Subtract, Multiply, Divide) HERE -->
</s:schema>
</types>
<message name="AddSoapIn">
<part name="parameters" element="s0:Add" />
</message>
<message name="AddSoapOut">
<part name="parameters" element="s0:AddResponse" />
</message>
<!-- OTHER MESSAGES (for Subtract, Multiply, Divide) HERE -->
<portType name="MathServiceSoap">
<operation name="Add">
<input message="s0:AddSoapIn" />
<output message="s0:AddSoapOut" />
</operation>
<!-- OTHER PORT TYPE OPERATIONS (for Subtract, Multiply, Divide) HERE -->
</portType>
<binding name="MathServiceSoap" type="s0:MathServiceSoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" />
<operation name="Add">
<soap:operation soapAction="http://tempuri.org/Add" style="document" />
<input>
<soap:body use="literal" />
</input>
<output>
<soap:body use="literal" />
</output>
</operation>
<!-- OTHER SOAP BINDING OPERATIONS (for Subtract, Multiply, Divide) HERE -->
</binding>
<service name="MathService">
<port name="MathServiceSoap" binding="s0:MathServiceSoap">
<soap:address location="http://www.dotnetjunkies.com/quickstart/aspplus/samples/services/MathService/VB/MathService.asmx" />
</port>
</service>
</definitions>
</programlisting>
<p>RPC style operations behave just like functions in that, instead of
documents, values are passed in as parameters. Parameters can be of simple data
type (number, boolean), array, or object. The parameter type for the operation
is described in the WSDL's XML schema.</p>
<example>
<canvas debug="true" height="400" width="530">
<debug x="10" y="190" width="510" height="200" />
<dataset name="googleDset" />
<soap name="google" wsdl="http://api.google.com/GoogleSearch.wsdl">
<handler name="onload">
Debug.debug('google soap service loaded');
</handler>
<handler name="onerror" args="error">
Debug.debug('error: %w', error);
</handler>
<!-- See RPC chapter for details on remotecall and how dataobject is
used to data bind to RPC operation results. -->
<remotecall name="search" funcname="doGoogleSearch"
dataobject="googleDset">
<param value="'2TKUw4ZQFHJ84ByemZK0EXV0Lj+7xGOx'" />
<param value="${ s.text }" />
<param value="1" />
<param value="10" />
<param value="true" />
<param value="''" />
<param value="true" />
<param value="''" />
<param value="''" />
<param value="''" />
<handler name="ondata" args="value">
Debug.debug('search result: %w\n', value);
</handler>
</remotecall>
</soap>
<view x="10" y="10" layout="spacing: 5" >
<view layout="axis: x; spacing: 5">
<edittext id="s" text="SOAP" />
<button text="search"
onclick="Debug.debug('Invoking search...'); google.search.invoke()" />
</view>
<view width="505" height="140" bgcolor="silver" layout="axis: y" >
<view>
<datapath xpath="googleDset:/resultElements/item" pooling="true" />
<text width="200" datapath="title/text()" clip="true" />
<text x="205" width="300" datapath="URL/text()" clip="true" />
</view>
</view>
</view>
</canvas>
</example>
<p>The example demonstrates how a result value, which is actually a JavaScript
object, can be data bound through the dataobject attribute in remotecall. For
more details, see the remotecall section in the <a href="../developers/rpc-soap.html" target="laszlo-dguide" shape="rect">RPC chapter</a> of the <a href="../developers/" target="laszlo-dguide" shape="rect">Developer's Guide</a>. To read about passing complex type
parameters, read the <a href="../developers/rpc-soap.html" target="laszlo-dguide" shape="rect">SOAP chapter</a>.</p>
<p><b>See Also:</b></p>
<ul>
<li>
<sgmltag class="element" role="lz.rpc"><rpc></sgmltag>
</li>
<li>
<sgmltag class="element" role="lz.javarpc"><javarpc></sgmltag>
</li>
<li>
<sgmltag class="element" role="lz.xmlrpc"><xmlrpc></sgmltag>
</li>
<li>
<sgmltag class="element" role="lz.remotecall"><remotecall></sgmltag>
</li>
<li>
<a href="../developers/rpc.html" target="laszlo-dguide" shape="rect">Developer's Guide: RPC</a>
</li>
<li>
<a href="../developers/rpc-soap.html" target="laszlo-dguide" shape="rect">Developer's Guide: SOAP</a>
</li>
</ul>
</text>
</doc>
</class>
</library>
Cross References
Includes
Classes
- <class name="soap" extends="rpc">