Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding attributes to SOAP messages in node.js (node-soap)

Spent the last day banging my head with this, and would appreciate any help!

I am building an application which consumes a 3rd party SOAP web service. This is based on node.js and uses node-soap. Unfortunately the WSDL file is a little broken, and I need to work my way around it.

This is the code I am using:

var url = 'http://domainexample.com/ws/connectionService.cfc?wsdl';
var session = 'super secret string'
var args = { connectionID: session }

soap.createClient(url, function (err, client) {
    client.connectionService_wrapService['connectionservice.cfc'].isConnected(args, function (err, result) {
        console.log(result);
    });
});

This is the error I get. Most of the other methods work fine:

org.xml.sax.SAXException: Deserializing parameter \'connectionID\': could not find deserializer for type { http://www.w3.org/2001/XMLSchema}anyType'

This is the message generated by the method:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:impl="http://rpc.xml.cfml/
ws/ConnectionService.cfc" xmlns:intf="http://rpc.xml.cfml/ws/ConnectionService.cfc">
  <soap:Body>
    <impl:isConnected>
      <connectionID>super secret string</connectionID>
    </impl:isConnected>
  </soap:Body>
</soap:Envelope>

I found that the WSDL file does not have a proper type attribute defined for the connectionID parameter for some of the methods (such as this one). It should be xsd:string, which is what it is for the methods I call that do work.

After some playing around with SOAP UI I found adding a type attribute (xsi:type=xsd:string) to the connectionID part, and adding a schema (xmlns:xsd="http://www.w3.org/2001/XMLSchema") fixes it. This is the XML I need to generate:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:impl="http://rpc.xml.cfml/
ws/ConnectionService.cfc" xmlns:intf="http://rpc.xml.cfml/ws/ConnectionService.cfc">
  <soap:Body>
    <impl:isConnected>
      <connectionID xsi:type="xsd:string">auth-string-here</connectionID>
    </impl:isConnected>
  </soap:Body>
</soap:Envelope>

But I can't figure out for the life of me how I can do it via node soap. I tried to add a type using the attributes key, however it only seems to work when I have parent node and child node in the arguments.

So, if I pass this down:

var args = {
    test: {
        connectionID:
        {
            attributes: {
                'xsi:type': 'xsd:string'
            },
            $value: session
        }
    }
};

I get the following:

<impl:isConnected>
  <test>
    <connectionID xsi:type="xsd:string">super secret string</connectionID>
  </test>
</impl:isConnected>

But I only need one level, like this:

var args = {
    connectionID:
    {
        attributes: {
            'xsi:type': 'xsd:string'
        },
        $value: session
    }
};

So I get this:

<impl:isConnected>
    <connectionID xsi:type="xsd:string">super secret string</connectionID>
</impl:isConnected>

But that doesn't seem to be happening. In fact, It doesn't add a type attribute at all when I keep it to a single node. I also need to figure out a way of adding the extra schema in the call. I worked around it by manually adding it in the soap-node core code, but that isn't clean at all (I can live with it though).

Any ideas? I'm fairly new to SOAP, and I'm not having much luck at the moment.

Thanks!

like image 302
Potentiator Avatar asked Nov 29 '25 07:11

Potentiator


1 Answers

Currently Node-Soap does not allow to pass the "attributesKey" value at the client options and does not use one by default.

The only way I could make it work is by defining my own WSDL object (with open_wsdl(uri, options, callback) function), pass options at the second parameter (not including "attributesKey" as it won't assign it) but then to the generated object assign it like this:

open_wsdl(wsdlUrl, setupSoapWsdlConfig() /* Here you can pass other params as valueKey and xmlKey but not attributesKey */, (err, wsdl: WSDL) => {
   if ( err ) { reject(err); }
   this.wsdl = wsdl;
   wsdl.options.attributesKey = '$attributes'; // Specify attributesKey
   resolve(wsdl);
});
like image 186
José Manuel Blasco Avatar answered Nov 30 '25 21:11

José Manuel Blasco



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!