tags:

views:

1159

answers:

3

Guys, I'm stuck, banging my head off the desk for the past few hours.

I am trying to consume a service, and I have 8 other functions that I call that are almost IDENTICAL in nature to this one, but this one, results in a 'SOAP-ERROR: Encoding: Violation of encoding rules' error.

Heres the function call (wsdl omitted for security):

    function CanLoadProduct($data){

 $client = new SoapClient('wsdl-url');

 $params = array('username'  => $this->username,
     'password' => $this->password,
     'prod'  => $data['productid'],
     'mdn'  => $data['mdn']);

 try {
  $reply = $client->__soapCall("CanLoadProduct", $params);
 } catch (Exception $e) {
  echo 'Error: ',  $e->getMessage(), "\n";
  print_r($params);
  die();
 }

 if( $reply['result'] == 1 ){
  return TRUE;  // 1 = true
 } else {
  return FALSE;
 }

}

Ok so this function, connects to a webservice, the required elements are: username, password, prod, mdn, all 4 of which I supply as part of the $params array. Username/Pass are defined earlier, and do work fine, as the other 8 functions consume the web service without any problems.

The $data[] array (that I pass to the function), contains: $data['productid'] $data['mdn'] nothing else is used.

I am getting

SOAP-ERROR: Encoding: Violation of encoding rules

for some unexplained reason, and Googling this error gets me nowhere. Anyone else run into this? Running PHP 5.2.9-2. The strange thing is this is identical to this function which works 100%:

    function GetPIN($productid){

 $client = new SoapClient('wsdl-url');

 $params = array('username' => $this->username,
     'password' => $this->password,
     'prod'  => $productid);

 try {
  $reply = $client->__soapCall("GetPIN", $params);
 } catch (Exception $e) {
  echo 'Error: ',  $e->getMessage(), "\n";
  die();
 }
  return $reply;
}

Here is the WSDL (should have posted this first):

<?xml version="1.0" encoding="ISO-8859-1"?>
<definitions xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" 
    xmlns:tns="ready:test" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
    xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="ready:test">
<types>
<xsd:schema targetNamespace="ready:test"
>
 <xsd:import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
 <xsd:import namespace="http://schemas.xmlsoap.org/wsdl/" />
</xsd:schema>
</types>
<message name="CanLoadProductRequest">
  <part name="username" type="xsd:string" />
  <part name="password" type="xsd:string" />
  <part name="prod" type="xsd:string" />    
  <part name="mdn" type="xsd:string" />
  <part name="esn" type="xsd:string" /></message>
<message name="CanLoadProductResponse">
  <part name="result" type="xsd:int" /></message>
<portType name="CanLoadProductPortType">
  <operation name="CanLoadProduct">
    <input message="tns:CanLoadProductRequest"/>
    <output message="tns:CanLoadProductResponse"/>
  </operation>
</portType>

<binding name="CanLoadProductBinding" type="tns:CanLoadProductPortType">
  <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/&gt;
  <operation name="CanLoadProduct">
    <soap:operation soapAction="{url-removed}" style="rpc"/>
    <input>
        <soap:body use="encoded" namespace="" 
           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/&gt;
    </input>
    <output>
        <soap:body use="encoded" namespace="" 
            encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/&gt;
    </output>
  </operation>
</binding>
<service name="CanLoadProduct">
  <port name="CanLoadProductPort" binding="tns:CanLoadProductBinding">

    <soap:address location="{url-removed}"/>
  </port>
</service>
</definitions>
+2  A: 

It looks like you have a type mismatch somewhere, either while assembling your request (one of the parameters is not of type string), or the server returns something other than an int (violating the WSDL response definition and thus causing the client to consider the response invalid, as it expects something else).

  • To test the first case, ensure casting all parameters to string first
  • To test the second case, create your SoapClient with the trace option set to true in order to gain access to the actual XML answer from the server via $client->__getLastResponse() afterwards (You can use this for request debugging also via __getLastRequest()).

Some additional observations/questions:

  • According to the posted WSDL, the 'CanLoadProductRequest' has a fifth param 'esn', which you do not supply in your function call.
  • Any reason why you use $client->__soapCall("CanLoadProduct", $params) instead of $client->CanLoadProduct($username, $password, etc.)? (The first version is a lower level variation which is intended to be used for non_WSDL scenarios. The second version might give you a more detailed error/exception)
  • Can you test the SOAP Call to CanLoadProductRequest by some other means? The error could be on the server side, trying to return a result type that does not fit the WSDL definition.
Henrik Opel
The 'esn' is optional, and this pattern of data user/pass/prod/mdn/esn is standard for most of the other 8 calls that I use, none seem to fail except for this one.I have tried $client->CanLoadProduct($params), but it results in: Array to string conversion Notice from PHP
Jakub
Oups - sorry, if you use the $client->CanLoadProduct() notation, you do not pass an array of parameters, but the single parameters as you would with a standard function call (e.g. $client->CanLoadProduct($username, $password, etc.)))
Henrik Opel
Another thing to try would be explicitly casting the parameters to string before the call (e.g. the productid might be passed as an int here)
Henrik Opel
Edited Answer according to new assumptions taken from the comments.
Henrik Opel
I have marked this as answer, because it helped me check off all possible issues. I concluded the WSDL was causing the error as it is such a simple SOAP call, and I ended up not using it as it was a 'check' call, and the post check function would return a fail message if it did not go through which worked as a check as well. I brought the issue up with the designer of the API. Thanks for your help everyone!
Jakub
A: 

I had the same problem when trying to pass XML as a parameter to one of my webservices. Wrapping the XML data in <![CDATA[ ... ]]> got rid of the SOAP-ERROR: Encoding: Violation of encoding rules and everything worked fine.

Other details:
1. The parameter was defined as xsd:string as well.
2. WSDL was document/literal.
3. Using built in SOAP class with php 5.2.10.

Shane
A: 

I was getting this error using the SoapUI tool, until I reformatted the response with real test data and not just '?'. Also with SoapUI, the response may be more than expected and may have to shorten to the expected response by removing serveral optional response parameters. Hope this helps?

Patrick Ingle