GetSpeech Failed - Incorrect Parameter Name c-gensym

This section provides a tutorial example on how to use a SOAP::Lite client to call a Web service with correct SOAPAction. But the test failed because of incorrect input parameter name c-gensym.

To fix the error in the previous tutorial, we need to set SOAPAction with the correct value. But how to do this? Which SOAP::Lite function to use?

Looking at the ActivePerl SOAP::Lite manual, it has this function:

on_action()
   This lets you specify a handler for on_action event. It is 
   triggered when creating SOAPAction. The default handler will set
   SOAPAction to "uri#method". You can change this behavior globally
   (see DEFAULT SETTINGS) or locally, for a particular object.

The online SOAP::Lite manual has a better explanation and two examples at http://search.cpan.org/~mkutter/SOAP-Lite-0.710.10/lib/SOAP/Lite.pm.

The second example is exactly what I need to fix my error:

.NET web services usually expect / as separator for uri and method. 
To change SOAP::Lite's behaviour to use uri/method as SOAPAction 
header, use the following code:
   $client->on_action( sub { join '/', @_ } );

Based on the above example I revised my test program as GetSpeech_SOAPAction.pl:

#- GetSpeech_SOAPAction.pl
#- Copyright (c) 2009 by Dr. Herong Yang, herongyang.com
#- All rights reserved
#
   use SOAP::Lite +trace;
   my $client = SOAP::Lite->new();
   $client->proxy('http://www.xmlme.com/WSShakespeare.asmx');

#- Fixing the SOAPAction header line - join uri and method name with /
   $client->uri('http://xmlme.com/WebServices');
   $client->on_action(sub { join '/', @_ });

#- Call the server
   my $som = $client->GetSpeech("To be, or not to be");
   my $output = $som->result;
   print $output . "\n";

Here is what I did in this program:

When executing GetSpeech_SOAPAction.pl, I got this:

C:\herong\ws_20080000\cod>GetSpeech_SOAPAction.pl
...
SOAP::Transport::HTTP::Client::send_receive: 
POST http://www.xmlme.com/WSShakespeare.asmx
Accept: text/xml
Accept: multipart/*
Content-Length: 540
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>
...
SOAP::Transport::HTTP::Client::send_receive: 
HTTP/1.1 500 Internal Server Error
Cache-Control: private
Connection: close
Date: ... 2009
Server: Microsoft-IIS/6.0
Content-Length: 623
Content-Type: text/xml; charset=utf-8
Client-Date: ... 2009
Client-Response-Num: 1
X-AspNet-Version: 2.0.50727
X-Powered-By: ASP.NET

<?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>
...

The Web service server failed again with a "HTTP/1.1 500 Internal Server Error". It was caused by a different exception in the Web service process: "System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.NullReferenceException: Object reference not set to an instance of an object."

The description of this exception is very generic. It tells us nothing about the root cause of the problem. But reviewing the request message in the trace output tells me that:

I will modify my program to provide the correct name for the request parameter in the next tutorial.

Last update: 2009.

Table of Contents

 About This Book

 Introduction to Web Service

 Introduction to SOAP (Simple Object Access Protocol)

 SOAP Message Structure

 SOAP Message Transmission and Processing

 SOAP Data Model

 SOAP Encoding

 SOAP RPC Presentation

 SOAP Properties Model

 SOAP Message Exchange Patterns

 SOAP HTTP Binding

 SOAP Perl Implementations

 SOAP PHP Implementations

 SOAP Java Implementations

 Perl SOAP::Lite - SOAP Server-Client Communication Module

 Perl Socket Test Program for HTTP and SOAP

Perl SOAP::Lite for GetSpeech SOAP 1.1 Web Service

 GetSpeech Failed - Incorrect SOAPAction Header Line

GetSpeech Failed - Incorrect Parameter Name c-gensym

 Using Socket Program to Request Parameter Name

 GetSpeech Worked - Using SOAP::Data Class and on_action() Function

 GetSpeech_SOAP_1_1.pl - SOAP::Lite for SOAP 1.1 Web Service

 Perl SOAP::Lite 0.710 for SOAP 1.2 Web Services

 Perl SOAP::Lite 0.710 for WSDL

 PHP SOAP Extension Client Programs

 PHP SOAP Extension Server Programs

 Java Socket and HttpURLConnection for SOAP

 SAAJ - SOAP with Attachments API for Java

 SoapUI - SOAP Web Service Testing Tool

 WS-Security - SOAP Message Security Extension

 WS-Security X.509 Certificate Token

 Web Services and SOAP Terminology

 References

 PDF Printing Version