23

I'm trying to implement a client for National Rail Enquiries' SOAP Service (http://www.livedepartureboards.co.uk/ldbws/).

I stick the WSDL (http://realtime.nationalrail.co.uk/ldbws/wsdl.aspx) into http://soapclient.com/soaptest.html, but I get back the error message "Unable to handle request without a valid action parameter. Please supply a valid soap action."; what on earth should the action be?

Thanks, Stewart

edit:

I just used soapclient.com as a quick example. In my software, I send the following XML; I still get that I'm missing an action.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://thalesgroup.com/RTTI/2008-02-20/ldb/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:ldbt2="http://thalesgroup.com/RTTI/2008-02-20/ldb/types" xmlns:ldbt="http://thalesgroup.com/RTTI/2007-10-10/ldb/types" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:ct="http://thalesgroup.com/RTTI/2007-10-10/ldb/commontypes" >
 <SOAP-ENV:Body>
  <ldbt2:GetDepartureBoardRequest xmlns:ldbt2="http://thalesgroup.com/RTTI/2008-02-20/ldb/" >
   <ldbt2:numRows>5</ldbt2:numRows>
   <ldbt2:crs>WAT</ldbt2:crs>
   <ldbt2:filterCrs>GLD</ldbt2:filterCrs>
   <ldbt2:filterType>to</ldbt2:filterType>
   <ldbt2:timeOffset>0</ldbt2:timeOffset>
  </ldbt2:GetDepartureBoardRequest>
 </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Stewart
  • 261
  • 1
  • 2
  • 7
  • 1
    It most likely means that soapclient.com doesn't like the WSDL, for reasons of its own. The NRE web service works fine, though, I've used it myself. – skaffman Feb 14 '10 at 21:15
  • See http://stackoverflow.com/questions/128263/how-do-you-determine-a-valid-soapaction – Jono Feb 25 '13 at 20:53
  • 1
    In short, search the WSDL for the soapAction. See http://stackoverflow.com/questions/128263/how-do-you-determine-a-valid-soapaction – Jono Feb 25 '13 at 20:55

8 Answers8

19

If its a SOAP 1.1 service then you will also need to include a SOAPAction HTTP header field:

http://www.w3.org/TR/2000/NOTE-SOAP-20000508/#_Toc478383528

mythz
  • 141,670
  • 29
  • 246
  • 390
  • 1
    I get that much... but I can't for the life of me work out what should be in the SOAPAction field. – Stewart Feb 14 '10 at 21:25
  • 1
    It would be the same as what's in your SOAP body, i.e. GetDepartureBoardRequest or the fully qualified: http://thalesgroup.com/RTTI/2008-02-20/ldb/GetDepartureBoardRequest – mythz Feb 14 '10 at 21:28
  • 1
    I've tried that, but I get "Server did not recognize the value of HTTP Header SOAPAction: GetDepartureBoardRequest" – Stewart Feb 14 '10 at 21:36
  • have you tried using the fully qualified name including your namespace? – mythz Feb 14 '10 at 23:14
  • 2
    it should match the WSDL value of the SOAPAction – Deian Sep 15 '15 at 15:19
4

I have come across exactly the same problem when trying to write a client for the National Rail SOAP service with Perl.

The problem was caused because the Perl module that I'm using 'SOAP::Lite' inserts a '#' in the SOAPAction header ...

SOAPAction: "http://thalesgroup.com/RTTI/2008-02-20/ldb/#GetDepartureBoard"

This is not interpreted correctly by .NET servers. I found this out from Example 3-19 in O'Reilly's Programming Web Services with SOAP . The solution was given below in section 3-20, namely you need to explicitly specify the format of the header with the 'on_action' method.

print SOAP::Lite
  -> uri('urn:Example1')
  -> on_action(sub{sprintf '%s/%s', @_ })
  -> proxy('http://localhost:8080/helloworld/example1.asmx')
  -> sayHello($name)
  -> result . "\n\n";

My guess is that soapclient.com is using SOAP::Lite behind the scenes and so are hitting the same problem when talking to National Rail.

The solution is to write your own client so that you have control over the format of the SOAPAction header ... but you've probably done that already.

Luke Girvin
  • 13,221
  • 9
  • 64
  • 84
Richard Corfield
  • 2,489
  • 3
  • 21
  • 24
2

SOAPAction is required in SOAP 1.1 but can be empty ("").

See https://www.w3.org/TR/2000/NOTE-SOAP-20000508/#_Toc478383528

"The header field value of empty string ("") means that the intent of the SOAP message is provided by the HTTP Request-URI."

Try setting SOAPAction=""

andre.wiik
  • 31
  • 2
1

When soapAction is missing in the SOAP 1.2 request (and many clients do not set it, even when it is specified in WSDL), some app servers (eg. jboss) infer the "actual" soapAction from {xsd:import namespace}+{wsdl:operation name}. So, to make the inferred "actual" soapAction match the expected soapAction, you can set the expected soapAction to {xsd:import namespace}+{wsdl:operation name} in your WS definition (@WebMethod(action=...) for Java EE)

Eg. for a typical Java EE case, this helps (not the Stewart's case, National Rail WS has 'soapAction' set):

@WebMethod(action = "http://packagename.of.your.webservice.class.com/methodName")

If you cannot change the server, you will have to force client to fill soapAction.

jvperrin
  • 3,368
  • 1
  • 23
  • 33
0

I've just spent a while trying to get this to work an have a written a Ruby gem that accesses the API. You can read more on it's project page.

This is working code in Ruby:

require 'savon'
client = Savon::Client.new do
  wsdl.document = "http://realtime.nationalrail.co.uk/LDBWS/wsdl.aspx"
end

response = client.request 'http://thalesgroup.com/RTTI/2012-01-13/ldb/GetDepartureBoard' do

  namespaces = {
    "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.xml do |xml|
    xml.soap(:Envelope, namespaces) do |xml|
      xml.soap(:Header) do |xml|
        xml.AccessToken do |xml|
          xml.TokenValue('ENTER YOUR TOKEN HERE') 
        end
      end
      xml.soap(:Body) do |xml|
        xml.GetDepartureBoardRequest(xmlns: "http://thalesgroup.com/RTTI/2012-01-13/ldb/types") do |xml|
          xml.numRows(10)
          xml.crs("BHM")
          xml.filterCrs("BHM")
          xml.filterType("to")
        end
      end
    end
  end
end
p response.body

Hope that's helpful for someone!

iHiD
  • 2,450
  • 20
  • 32
0

We put together Web Services on Windows Server and were trying to connect with PHP on Apache. We got the same error. The issue ended up being different versions of the Soap client on the different servers. Matching the SOAP versions in the options on both servers solved the issue in our case.

j0k
  • 22,600
  • 28
  • 79
  • 90
jessier3
  • 809
  • 1
  • 7
  • 16
0

the service have 4 operations: 1. GetServiceDetails 2. GetArrivalBoard 3. GetDepartureBoard 4. GetArrivalDepartureBoard

Implementation of web service

antonio
  • 548
  • 8
  • 16
0

I have solved this problem, in Java Code, adding:

 MimeHeaders headers = message.getMimeHeaders();
 headers.addHeader("SOAPAction", endpointURL);
Antonios
  • 1
  • 1