Adem
Adem

Reputation: 9429

How can I add "namespace" to request in node soap

I created web service object from wsdl file and call it like in below. I also print result. this code does not work. web server returns error. because, request has not namespace.

soap.createClient(__dirname + '/wsdl/getCustomerDetails.wsdl', function(err, client) {
.
.
var params=  {"custId":"123"};
client.getCustomerDetails.getCustomerDetailsPort.getCustomerDetails(params,function(err,result){
    console.log("lastRequest:"+client.lastRequest);
    if (err != null)
        console.log("error:"+JSON.stringfy(error));

});

}

here what I see in the last request

<soap:...  xmlns:tns="http://example.com/api/getCustomerDetails/V01" >
....
  <soap:Body>
     <getCustomerDetailsRequest>
         <custId>123</custId>
     </getCustomerDetailsRequest>
  </soap:Body>...

but it has to be

<soap:...  xmlns:tns="http://example.com/api/getCustomerDetails/V01" >
    ....
   <soap:Body>
     <tns:getCustomerDetailsRequest>
        <tns:custId>123</tns:custId>
     </tns:getCustomerDetailsRequest>
   </soap:Body>...

as you see, soap module does not add tns namespace to the request. I tried var params= {"tns:custId":"123"};, it adds namespace to the parameter, but still it does not add namespace to the request, getCustomerDetailsRequest. because of that, I get Unexpected element getCustomerDetailsRequest found. Expected {http://example.com/api/getCustomerDetails/V01}getCustomerDetailsRequest.

how can I force to add this namespace to the method itself ?

Upvotes: 11

Views: 15529

Answers (2)

Rafael Medeiros
Rafael Medeiros

Reputation: 1283

I dwelt sometime on this problem until I saw that the lib get the namespaces from the parsed WSDL (this.wsdl.xmlnsInEnvelope)

xml = '<?xml version="1.0" encoding="utf-8"?>' +
        '<' + envelopeKey + ':Envelope ' +
        xmlnsSoap + ' ' +
        'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ' +
        encoding +
        this.wsdl.xmlnsInEnvelope + '>' +

Then I saved the WSDL inside my project (loading from there) and inserted the namespace I wanted. That worked for me.

Upvotes: 1

Adem
Adem

Reputation: 9429

I found how I can do that. I think it does not work in default because of a bug in "soap" module. In default, it does not add namespace to the request body. "soap" uses "tns" in default as namespace. there is an option in wsdlOptions. it is overrideRootElement. If you try to override overrideRootElement with tns, it does not add tns to the request body. You have to use different namespace in overrideRootElement. Here my solution,

I first create my wsdlOptions object.

var wsdlOptions = {
  "overrideRootElement": {
    "namespace": "myns",
    "xmlnsAttributes": [{
      "name": "xmlns:myns",
      "value": "http://example.com/api/getCustomerDetails/V01"
    }]
  }
};

and then use it when I create soap client,

soap.createClient(__dirname + '/wsdl/getCustomerDetails.wsdl',wsdlOptions, function(err, client) {
.
.
.
}
);

It makes request body uses myns as namespace of root element. Now, I have to modify parameters' namespace, so I defined parameters as

var params=  {"myns:custId":"123"};

now, It creates request as

<soap:...  xmlns:tns="http://example.com/api/getCustomerDetails/V01" >
    ....
   <soap:Body>
     <myns:getCustomerDetailsRequest xmlns:myns="http://example.com/api/getCustomerDetails/V01">
        <myns:custId>123</tns:custId>
     </myns:getCustomerDetailsRequest>
   </soap:Body>...

and, now webserver accepts it.

keep in mind, even tns is defined in the root, it is not added to the request body automatically. Also, if you try to override it in wsdlOptions by tns again, it still does not work. You have to use different value as namespace, like myns

Upvotes: 21

Related Questions