Wednesday, May 30, 2012

Coldfusion, SOAP headers and custom namespaces

Some webservices require you to add specific headers to your request (i.e. for authentication). In the CFML reference you can find a function AddSOAPRequestHeader which can do this for you. The problem is that the documentation is not always very clear about HOW you should use this.
My problem was that the header should use some custom namespaces and some default namespaces, here is how you should do this.
My SOAP header should look like this:

<soapenv:header>
<ws:authenticationheader>
<username>[username here]</username>
<password>[password here]</password>
</ws:authenticationheader>
</soapenv:header>

There is a namespace "ws" defined in the soapenv:Envelope pointing to a custom namespace. It is still (as far as I could research) impossible to define this in the soapenv. Second best is to define this in the header itself.

XmlHeader = XmlNew();
XmlHeader.xmlRoot = XmlElemNew(XmlHeader,"http://www.url-to-ns","ws:AuthenticationHeader");
XmlHeader.xmlRoot.XmlChildren[1] = XmlElemNew(XmlHeader,"","username");
XmlHeader.xmlRoot.XmlChildren[2] = XmlElemNew(XmlHeader,"","password");
XmlHeader.xmlRoot.username.XmlText = "[username here];
XmlHeader.xmlRoot. username .XmlAttributes['xsi:type'] = "xsd:string";
XmlHeader.xmlRoot.Password.XmlText = "[password here]";
XmlHeader.xmlRoot.Password.XmlAttributes['xsi:type'] = "xsd:string";
AddSOAPRequestHeader(varnameOfWS," http://www.url-to-ns ","ws:AuthenticationHeader",XmlHeader,false);
result = varnameOfWS.doSomething();

From the CF documentation:
XmlElemNew(xmlObj[, namespace], childName)
The trick is to add the namespace alias to childName parameter using the format "[alias]:childname", the namespace alias then is automatically added.

Here is the soap header using soap_req = getSOAPRequest(varnameOfWS);


<soapenv:Header>
<ws:AuthenticationHeader 
soapenv:actor="" 
soapenv:mustUnderstand="0" 
xmlns:ws="http://www.url-to-ns">
<username xmlns="" xsi:type="xsd:string">[username here]</username>
<password xmlns="" xsi:type="xsd:string">[password here]</password>
</ws:AuthenticationHeader>
</soapenv:Header>


The namespace definition is valid for the web service which was my goal. I would rather see the definition in the soapenv:Envelope so if anyone knows how to do this please let me know! :)

No comments:

Post a Comment