Creating a SOAP client

#1

I’m looking for a way to send SOAP request to a web service, with a WSDL. Is it possible to do that with Typescript 2 and Angular 2 ?

I’ve seen tutorials for Angular 1 but they used old angular methodes, like factory or controller.

I would like if it’s possible, a new way to do that with TypeScript.

Any ideas ?

#2

Hello @Calliste, refer given links:


#3

Please, if you can avoid it… never ever use SOAP (XML) WebService with a webapp written in JavaScript.
Converting complex XML to JSON is very slow, you have to be sure, that you receive valid XML that can be transformed to JSON --> in most cases you have to use thirdparty library to do that.

And again an API should be blazing fast for mobile apps… so soap is maybe not the right choice ^^.

#4

Hi! Calliste… could you solve this problem?
Could you tell me how you solved it?
I need create a client soap web services and I have a problem when I want include autopulous-angular2-soap.
Thanks.

#5

Yeah I found a solution but not really with autopulous trick. :slight_smile:
It consists to use a classical http request with ajax and I send in argument my xml. Considering that I’ve a tomcat server running and has to return me a square number. You can take a look at the following code :

soapCall() {
            var xmlhttp = new XMLHttpRequest();
            xmlhttp.open('POST', 'http://10.0.2.2:8080/MathsTest/services/MathsUtilityPort?wsdl', true);
            var input_element = <HTMLInputElement> document.getElementById("choosenNumber");
            console.log("chVal : " + this.chVal);
            this.choosenNumberValue = this.chVal;
            //the following variable contains my xml soap request (that you can get thanks to SoapUI for example)
            var sr =
                `<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:mat="http://mathsutility.test.com/">
              <soapenv:Header/>
              <soapenv:Body>
                <mat:carreNombre>
                    <arg0>` + this.choosenNumberValue + `</arg0>
                </mat:carreNombre>
              </soapenv:Body>
            </soapenv:Envelope>`;

            xmlhttp.onreadystatechange =  () => {
                if (xmlhttp.readyState == 4) {
                    if (xmlhttp.status == 200) {
                        var xml = xmlhttp.responseXML;
                        this.response_number = parseInt(xml.getElementsByTagName("return")[0].childNodes[0].nodeValue); //Here I'm getting the value contained by the <return> node
                        console.log(this.response_number); //I'm printing my result square number
                    }
                }
            }
            // Send the POST request
            xmlhttp.setRequestHeader('Content-Type', 'text/xml');
            xmlhttp.responseType = "document";
            xmlhttp.send(sr);
  }

Sorry to answer my own question late, if you need more precision don’t hesitate, I can edit my post.

3 Likes
#6

OK!! Thanks a lot!
I will try to implement your solutions

#7

I could not understand where “this.chVal” comes from?

#8

Hi, in my example I used a server to return a square number of the variable chVal which is a value I want to send by entering it inside an hml input element. Consider in that case that it’s just the argument you want to send with SOAP.

#9

@Calliste i have the same issue " I’m looking for a way to send SOAP request to a web service, with a WSDL. Is it possible to do that with Typescript 2 and Angular 2 ?

I’ve seen tutorials for Angular 1 but they used old angular methodes, like factory or controller.

I would like if it’s possible, a new way to do that with TypeScript.

Any ideas ? "

But now the requests am sending is for authentication purposes “login”…can you help an example would help.

thank you

#10

Hi catter_njenga,

Yes you can use Typescript and Angular 2 to send soap request. For my part I used that in my previous example.

In Typescript you can write basic Javascript code, so my way can work. To do that, you just have to create a soapCall function according to my own answer published the 16 November.

If you have questions, you can ask me here :wink:

#12
This is my response, now i need to display the returned response....ie 
 <return>Invalid Credentials</return>

    <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
       <S:Body>
          <ns2:confirmloginResponse xmlns:ns2="http://service.mobile.web/">
             <return>Invalid Credentials</return>
          </ns2:confirmloginResponse>
       </S:Body>
    </S:Envelope>

Please Advise..
#13

You get invalid credentials error, that means that your request sould be different. May be you need user authentification in header of your sended xml :wink:

If you want to display the result, just parse that into XML (if it’s not already the case) and then get the content of <return> node

#14

i used this code for .asmx service ,it works great but i used for wsdl service with basic authentication,it returns 401 error and i chose POSTprotocol but its protocol is OPTIONS(i dont understand)
Can you help me?

#15

Hi, so with AJAX when you start a call with POST methods, it always sends OPTIONS methods before automatically for security reasons. This is called ‘cors’ calls as you can see here : http://dev.housetrip.com/2014/04/17/unleash-your-ajax-requests-with-cors/
When the server receives an OPTION call it can authorize access (OK 200) or revoke access for future calls from the client. In all cases, it will give you the response. If the server says that you can’t access to him, you have to enable cors access to it. So it depends of your server (tomcat, apache, wildfly…) but basically you just have to modify config files.

For the 401 error, it’s seems that you are not authorized to access to the wsdl because you are not connected to the domain before. I think in the xml you send with the AJAX call you could add a <header/> like that :

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Header>
    <Authentication xmlns="your domain">
      <Password>string</Password>
      <UserName>string</UserName>
    </Authentication>
  </soap:Header>
  <soap:Body>
    ...
  </soap:Body>
</soap:Envelope>

taken from this URL : http://www.hibri.net/2006/11/26/adding-simple-authentication-to-a-web-service-using-soap-headers/

sorry for my english, I hope that will help you

#16
var sr ='<?xml version="1.0" encoding="utf-8"?>'+
            '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:rxm="domain.com">'+
             '<soapenv:Header/>'+
			  '<soap:Body>'+
                 ........
			  '</soap:Body>'+
			'</soap:Envelope>';

or

var sr ='<?xml version="1.0" encoding="utf-8"?>'+
            '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://rxmpws.com/">'+
             '<soap:Header>'+
			    '<Authentication xmlns="http://domain.com/">'+
			      '<Password>password</Password>'+
			      '+<UserName>username</UserName>'+
			    '</Authentication>'+
			  '</soap:Header>'+
                        '<soapenv:Body>'+
                           ........
                        '</soapenv:Body>'+
			'</soapenv:Envelope>';

and my request code:

var xmlhttp = new XMLHttpRequest();
            xmlhttp.onreadystatechange = function () {
                if (xmlhttp.readyState == 4) {
                    if (xmlhttp.status == 200) {
                        //alert('done. use firebug/console to see network response');
                        alert(xmlhttp.response);
                    }
                }
            }
            xmlhttp.open('POST', 'http://domain.com', true);

            xmlhttp.setRequestHeader("Access-Control-Allow-Origin", "*");
            xmlhttp.setRequestHeader("Access-Control-Allow-Credentials", "true");
            xmlhttp.setRequestHeader("Access-Control-Allow-Headers", "...All Headers...");
            xmlhttp.setRequestHeader('Content-Type', 'text/xml charset=UTF-8');
            xmlhttp.setRequestHeader('Authorization', 'Basic ' + btoa('username:password'));
            xmlhttp.setRequestHeader("SOAPAction", "http://action.com");
            xmlhttp.responseType = "document";
			xmlhttp.send(sr);

my request:

OPTIONS http://domain.com/wsdl  HTTP/1.1
Host: www.domain.com
Connection: keep-alive
Access-Control-Request-Method: POST
Origin: http://localhost:8100
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36 OPR/46.0.2597.46
Access-Control-Request-Headers: access-control-allow-credentials,access-control-allow-headers,access-control-allow-origin,authorization,content-type,soapaction
Accept: */*
DNT: 1
Referer: http://localhost:8100/
Accept-Encoding: gzip, deflate
Accept-Language: tr-TR,tr;q=0.8,en-US;q=0.6,en;q=0.4

response:

HTTP/1.1 401 Unauthorized
Content-Type: text/html
Server: Microsoft-IIS/8.5
WWW-Authenticate: Basic realm="www.domain.com"
X-Powered-By: ASP.NET
Date: Wed, 19 Jul 2017 06:43:09 GMT
Content-Length: 1291
Via: 1.1 google
Set-Cookie: GCLB=CL3-hIuTjsSiJw; path=/; HttpOnly

<html> ... </html>

if i send request for Soap UI,it is sending 2 request (i dont know)
1st request:

POST http://domain.com/wsdl HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: text/xml;charset=UTF-8
SOAPAction: "http://action.com"
Content-Length: 547
Host: 130.211.17.101
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.5.2 (Java/1.8.0_112)

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:rxm="http:domain.com">
   <soapenv:Header/>
   <soapenv:Body>
      .........
   </soapenv:Body>
</soapenv:Envelope>

and 1st response(it is the same of my response)(failure):

HTTP/1.1 401 Unauthorized
Content-Type: text/html
Server: Microsoft-IIS/8.5
WWW-Authenticate: Basic realm="ip address of domain.com"
X-Powered-By: ASP.NET
Date: Wed, 19 Jul 2017 06:52:35 GMT
Content-Length: 1293
Via: 1.1 google
Set-Cookie: GCLB=CKS7g9PK-_eqEA; path=/; HttpOnly

<html>...</html>

2nd request:

POST htt://domain/wsdl HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: text/xml;charset=UTF-8
SOAPAction: "http://action.com"
Content-Length: 547
Host: 130.211.17.101
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.5.2 (Java/1.8.0_112)
Authorization: Basic ...string of btoa(username:password)..

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:rxm="http:/domain.com/">
   <soapenv:Header/>
   <soapenv:Body>
    ............
   </soapenv:Body>
</soapenv:Envelope>

2nd response(success)

HTTP/1.1 200 OK
Cache-Control: private
Content-Length: 14564
Content-Type: text/xml; charset=utf-8
Server: Microsoft-IIS/8.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Wed, 19 Jul 2017 06:52:35 GMT
Via: 1.1 google
Set-Cookie: GCLB=CPaTjbS8mcTbCg; path=/; HttpOnly

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

I don’t unterstand why it does not work for wsdl with authentication, it woks asmx without authentication but it does not work wsdl with authentication .
Thanks

#17

Hi,
I don’t really understand for soapUI. Normally it should send just one request and if I compare the first request and the second one, I see that the second one send additional informations like the Authorization.

Concerning the AJAX request, it’s normal because as I said with AJAX when you send POST request it automatically send OPTIONS request before and if your server is not configured for cors access, it will always revoke OPTIONS request.

#18

It worked, I disabled web security of chrome and it worked, because cors is able for localhost:8080 but ionic runs localhost:8100. For device, I toke bad request and I changed my request after then it worked.
Thanks

#19

Hi Guys, just in case anyone is still struggling, I have just upgraded the original angular-soap to make it work with typescript and Ionic2, take a look https://github.com/infoxicator/angular2-soap

#20

It worked me, Do you know if i can get images base64 with this SOAP Client?

#21

Yes, I have tested encoding base64 images and it works fine. By the way, I have fixed a bug with the parameters duplicating, please check github for more info. https://github.com/infoxicator/angular2-soap

1 Like