This section provides a tutorial example on how to use my socket test program, SocketRequestResponseBinary.pl, to play with the SOAP 1.1 request generated in the trace output of my SOAP::Lite test program.
In the previous tutorial, I noticed that the SOAP request message has the parameter element
name set to "c-gensym3". But the GetSpeech Web service expects an element name of "Request".
Before looking at how to change the parameter element name with SOAP::Lite,
I want to my socket test program .pl to perform some quick tests
with the request generated by SOAP::Lite in the previous tutorial.
Based on the trace output GetSpeech_SOAPAction.pl,
I prepared this socket request file, GetSpeech_SOAPAction.req:
POST /WSShakespeare.asmx HTTP/1.1
Host: www.xmlme.com
Accept: text/xml
Accept: multipart/*
Content-Length: 589
Content-Type: text/xml; charset=utf-8
SOAPAction: http://xmlme.com/WebServices/GetSpeech
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/1999/XMLSchema"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<namesp1:GetSpeech xmlns:namesp1="http://xmlme.com/WebServices">
<c-gensym3 xsi:type="xsd:string">To be, or not to be</c-gensym3>
</namesp1:GetSpeech>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Here is what I did to convert the trace output of GetSpeech_SOAPAction.pl to this request file:
Modified the POST command line.
Inserted the "Host" header line.
Reformatted the request XML message, without changing any structure.
Updated the value of Content-Length to match the number of bytes of the reformatted XML message.
I am ready to send this request file to the server with SocketRequestResponseBinary.pl:
\herong>SocketRequestResponseBinary.pl www.xmlme.com 80
GetSpeech_SOAPAction.req GetSpeech_SOAPAction.res
\herong>>type GetSpeech_SOAPAction.res
HTTP/1.1 500 Internal Server Error
Connection: close
Date: ... 2009
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Cache-Control: private
Content-Type: text/xml; charset=utf-8
Content-Length: 623
<?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">
<soap:Body>
<soap:Fault>
<faultcode>soap:Server</faultcode>
<faultstring>
System.Web.Services.Protocols.SoapException:
Server was unable to process request. --->
System.NullReferenceException: Object reference not set
to an instance of an object.
at WSShakespeare.Shakespeare.GetSpeech(String Request)
--- End of inner exception stack trace ---
</faultstring>
<detail />
</soap:Fault>
</soap:Body>
</soap:Envelope>
Ok. I got the same exception as my GetSpeech_SOAPAction.pl program.
Now let me modify the request XML message based on my analysis in the previous tutorial,
GetSpeech_Parameter_Name.req:
POST /WSShakespeare.asmx HTTP/1.1
Host: www.xmlme.com
Accept: text/xml
Accept: multipart/*
Content-Length: 619
Content-Type: text/xml; charset=utf-8
SOAPAction: http://xmlme.com/WebServices/GetSpeech
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/1999/XMLSchema"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<namesp1:GetSpeech xmlns:namesp1="http://xmlme.com/WebServices">
<namesp1:Request xsi:type="xsd:string">
To be, or not to be
</namesp1:Request>
</namesp1:GetSpeech>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Here is what I did to try to fix the parameter name issue in the request XML message:
Replaced c-gensym3 with namesp1:Request. "Request" is the required parameter name
according to the GetSpeech request sample. "namesp1:" is the namespace of
the parent element "GetSpeech". This is to make sure that the name "Request" is under
an existing namespace.
Updated the value of Content-Length to match the number of bytes of the reformatted XML message.
I am ready to test this new socket request:
\herong>SocketRequestResponseBinary.pl www.xmlme.com 80
GetSpeech_Parameter_Name.req GetSpeech_Parameter_Name.res
\herong>type GetSpeech_Parameter_Name.res
HTTP/1.1 200 OK
Connection: close
Date: ... 2009
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Cache-Control: private, max-age=0
Content-Type: text/xml; charset=utf-8
Content-Length: 1942
<?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">
<soap:Body>
<GetSpeechResponse xmlns="http://xmlme.com/WebServices">
<GetSpeechResult><SPEECH><PLAY>HAMLET</PLAY>
<SPEAKER>HAMLET</SPEAKER>To be, or not to be:
that is the question: Whether 'tis nobler in the mind
...</SPEECH>
</GetSpeechResult>
</GetSpeechResponse>
</soap:Body>
</soap:Envelope>
The modified request worked!
I will to back to my GetSpeech_SOAPAction.pl program
and try to find the SOAP::Lite function to generate the correct parameter name
in the next tutorial.