SOAP-ERROR:编码:违反编码规则?

2021-12-24 00:00:00 xml php soap

伙计们,我被困住了,在过去的几个小时里我的头从桌子上摔下来.

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

我正在尝试使用一项服务,并且我调用了其他 8 个函数,它们本质上与这个函数几乎相同,但是这个函数会导致SOAP-ERROR: Encoding: Violation of encoding rules"错误.

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.

这里是函数调用(为安全起见省略了 wsdl):

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(), "
";
        print_r($params);
        die();
    }

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

}

好的,这个函数,连接到一个webservice,需要的元素是:用户名、密码、prod、mdn,我将所有这 4 个作为 $params 数组的一部分提供.用户名/通行证定义较早,并且工作正常,因为其他 8 个函数使用 Web 服务没有任何问题.

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.

$data[] 数组(我传递给函数的)包含:$data['productid']$data['mdn']没有使用其他任何东西.

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

我得到了

SOAP-ERROR: Encoding: Violation of encoding rules

出于某种无法解释的原因,谷歌搜索这个错误让我无处可去.还有人遇到这个吗?运行 PHP 5.2.9-2.奇怪的是,这与这个 100% 有效的函数相同:

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(), "
";
        die();
    }
        return $reply;
}

这是 WSDL(应该先发布这个):

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"/>
  <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>

推荐答案

看起来您的某处类型不匹配,要么在组装请求时(其中一个参数不是字符串类型),要么服务器返回其他内容而不是 int(违反 WSDL 响应定义,从而导致客户端认为响应无效,因为它期望其他内容).

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

  • 要测试第一种情况,请确保首先将所有参数转换为字符串
  • 要测试第二种情况,请创建您的 SoapClient,并将 trace 选项设置为 true,以便之后通过 $client->__getLastResponse() 从服务器获得对实际 XML 答案的访问(您也可以通过 __getLastRequest() 将其用于请求调试.
  • 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:

  • 根据已发布的 WSDL,CanLoadProductRequest"具有第五个参数esn",您不会在函数调用中提供该参数.
  • 您使用 $client->__soapCall("CanLoadProduct", $params) 而不是 $client->CanLoadProduct($username, $password, etc.) 的任何原因?(第一个版本是一个较低级别的变体,旨在用于非 WSDL 场景.第二个版本可能会为您提供更详细的错误/异常)
  • 您能否通过其他方式测试对 CanLoadProductRequest 的 SOAP 调用?错误可能在服务器端,试图返回不符合 WSDL 定义的结果类型.
  • 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.

相关文章