2009-08-20 30 views
9

Chicos, estoy atascado, golpeando mi cabeza en el escritorio durante las últimas horas.SOAP-ERROR: Codificación: ¿Violación de las reglas de codificación?

Estoy tratando de consumir un servicio, y tengo otras 8 funciones que llamo que son casi IDÉNTICAS en naturaleza a esta, pero esta, da como resultado un 'SOAP-ERROR: Codificación: violación de las reglas de codificación' error.

Aquí está la llamada de función (WSDL se omite por seguridad):

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 por lo que esta función, se conecta a un servicio web, los elementos necesarios son: nombre de usuario, contraseña, prod, MDN, todos los 4 de los cuales Suministro como parte de la matriz de $ params. El nombre de usuario/Pase se definieron anteriormente, y funcionan bien, ya que las otras 8 funciones consumen el servicio web sin ningún problema.

Los datos de $ [] array (que me pase a la función), contiene: $ data [ 'idproducto'] $ data [ 'MDN'] nada más se utiliza.

estoy recibiendo

SOAP-ERROR: Encoding: Violation of encoding rules 

por alguna razón inexplicable, y buscar en Google este error me lleva a ninguna parte. ¿Alguien más se encuentra con esto? Ejecutando PHP 5.2.9-2. Lo extraño es que esto es idéntico a esta función, que funciona al 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; 
} 

Aquí es el WSDL (debería haber publicado esta primera):

<?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"/> 
    <operation name="CanLoadProduct"> 
    <soap:operation soapAction="{url-removed}" style="rpc"/> 
    <input> 
     <soap:body use="encoded" namespace="" 
      encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> 
    </input> 
    <output> 
     <soap:body use="encoded" namespace="" 
      encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> 
    </output> 
    </operation> 
</binding> 
<service name="CanLoadProduct"> 
    <port name="CanLoadProductPort" binding="tns:CanLoadProductBinding"> 

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

Si se tratara de un cliente .NET, trataría de codificar "prod" y "mdn" para que sean conocidos, buenos valores y vea qué sucede. Si funciona, eliminaría los códigos duros de uno en uno para ver cuál es el problema. Luego miro el valor de falla para ver si hay algo especial al respecto. –

+0

Esa fue mi primera idea también. –

+0

Intenté hardcoding it, pero obtengo el mismo resultado, es MUY extraño. No conozco ningún otro método para solucionar este problema. – Jakub

Respuesta

14

Parece que tiene una coincidencia de tipos en alguna parte , ya sea al armar su solicitud (uno de los parámetros no es de tipo cadena), o el servidor devuelve algo que no sea int (violando la definición de respuesta WSDL y haciendo que el cliente considere inválida la respuesta, ya que espera algo más) .

  • Para probar el primer caso, garantizar la fundición de todos los parámetros de cadena de primera
  • Para probar el segundo caso, cree que su SoapClient con la opción traza establecido en true con el fin de obtener acceso a la respuesta XML real desde el servidor vía $ client -> __ getLastResponse() luego (Puede usar esto para depurar las solicitudes también a través de __getLastRequest()).

Algunas observaciones/preguntas adicionales:

  • De acuerdo con el WSDL publicado, el 'CanLoadProductRequest' tiene un parámetro quinta 'esn', que no se proporciona en su llamada a la función.
  • ¿Por qué usa $client->__soapCall("CanLoadProduct", $params) en lugar de $client->CanLoadProduct($username, $password, etc.)? (La primera versión es una variación de nivel inferior que se debe usar para escenarios no_WSDL. La segunda versión podría darle un error/excepción más detallada)
  • ¿Puede probar la llamada SOAP a CanLoadProductRequest de otra forma? El error podría estar en el lado del servidor, tratando de devolver un tipo de resultado que no se ajusta a la definición de WSDL.
+0

El 'esn' es opcional, y este patrón de datos user/pass/prod/mdn/esn es estándar para la mayoría de las otras 8 llamadas que uso, ninguna parece fallar a excepción de esta. He intentado $ cliente-> CanLoadProduct ($ params), pero resulta en: Conversión de matriz a cadena Aviso de PHP – Jakub

+0

Oups: disculpa, si usas la notación $ cliente-> CanLoadProduct(), no pasas una matriz de parámetros, pero los parámetros individuales como lo haría con una llamada a función estándar (por ejemplo, $ cliente-> CanLoadProduct ($ nombre de usuario, $ contraseña, etc.)) ) –

+1

Otra cosa que probar sería convertir explícitamente los parámetros en cadena antes la llamada (por ejemplo, el productid se puede pasar como int aquí) –

2

Tuve el mismo problema al intentar pasar XML como parámetro a uno de mis servicios web.Envolviendo los datos XML en <![CDATA[ ... ]]> se eliminó el SOAP-ERROR: Codificación: Violación de las reglas de codificación y todo funcionó bien.

Otros detalles:
1. El parámetro se definió como xsd: string también.
2. WSDL fue document/literal.
3. Usando una clase SOAP incorporada con php 5.2.10.

2

Estaba obteniendo este error con la herramienta SoapUI, hasta que formateé la respuesta con datos de prueba reales y no solo '?'. También con SoapUI, la respuesta puede ser más de lo esperado y puede tener que acortarse a la respuesta esperada eliminando varios parámetros de respuesta opcionales. ¿Espero que esto ayude?

+0

Este es también mi problema. Esperaba que se devolviera un número entero, ¿y obviamente? no es un int. –

+0

¿cómo puedo saber qué valor se espera devolver? –

1
<![CDATA[<?xml version="1.0" 
encoding="utf-8"?> 
<CONTENTXML></CONTENTXML]]></xmlCallString>]]> 
2

tuve el mismo problema y lo resuelve con esta sintaxis para __soapCall:

... 
$params = new SoapParam($data, 'parameters'); 

$response = $this->__soapCall('methodName', 
    array(new SoapVar($data, XSD_ANYTYPE, 'parameters')) 
);   
... 

En lugar de

__soapCall('methodName', array($params) 
6

que tenía el mismo problema.

En soapUI preferencias que marca la opción Preferencias → Editor de Configuración → Respuestas Validar y he recibido esta información:

line 3027: Invalid decimal value: unexpected char '44'.

Esto resolvió mi problema. El campo contenía un valor de tipo incorrecto.

+0

Esto me ayudó muchísimo con la depuración de mi wsdl. – Halfstop

+0

Preferencias se encuentra en "Archivo", y también puede activar "Validar solicitudes" para averiguar si está enviando el tipo incorrecto de datos en los ejemplos de prueba. – MatsLindh

0

Tuve el mismo problema, y ​​logré corregirlo corrigiendo el WSDL, que suponía que el servidor enviaría un entero para un valor particular, pero en realidad estaba enviando una cadena. Tal vez la modificación del WSDL a partir de:

<part name="result" type="xsd:int" /></message> 

a

<part name="result" type="xsd:string" /></message> 

puede resolver su problema, aquí hay alguna información sobre el caso particular que estaba enfrentando: https://blog.dotnetframework.org/2016/12/06/uncaught-soapfault-exception-sender-soap-error-encoding-violation-of-encoding-rules/

0

tuve este problema en PhpStorm cuando haciendo pruebas unitarias Inhabilité la memoria caché wsdl y funcionó: ini_set ("soap.wsdl_cache_ habilitado", "0");

Cuestiones relacionadas