2012-02-17 54 views
1

我写的基于Delcampe API的soap-client。简单的方法工作正常,但功能需要复杂的数据给我一个错误消息,如“你必须发送项目的数据!”。基于PHP示例here我认为,该数据应该是哈希或hashref,但都给我前面提到的错误。Perl:我应该向delcampe API提供什么样的数据?

示例脚本使用:

use 5.010; 
use SOAP::Lite; 
use SOAP::WSDL; 
use strict; 
use warnings; 
use Data::Dumper; 

my $API_key = 'xyz'; 
my $service = SOAP::Lite->service('http://api.delcampe.net/soap.php?wsdl'); 
my $return = $service->authenticateUser($API_key); 

if ($return->{status}) { 
    my $key = $return->{data}; 
    my %data = (description => 'updated description'); 
    my $response = $service->updateItem($key, 123456, \%data); 

    if ($response->{status}) { 
     say Dumper $response->{data}; 
    } else { 
     say $response->{errorMsg}; 
    } 
} else { 
    say "no: " . $return->{status}; 
} 

所以,我应该使用的,而不是%data什么样的数据结构,或者我怎么能调试SOAP信封,这是作为请求? (基于例如PHP代码工作正常)

ADDITION

use SOAP::Lite qw(trace);与IGOT SOAP信封太:

<?xml version="1.0" encoding="UTF-8"?> 
<soap:Envelope soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://api.delcampe.net/soap.php"> 
    <soap:Body> 
     <tns:updateItem> 
      <token xsi:type="xsd:string">secret_one</token> 
      <id_item xsi:type="xsd:int">123456</id_item> 
      <arrData xsi:nil="true" xsi:type="soap-enc:Array" /> 
     </tns:updateItem> 
    </soap:Body> 
</soap:Envelope> 

如上所示,没有发送的数据的比特。我也尝试数据作为字符串,数组和阵列参考。也许这是SOAP::Lite的错误?

+0

你有没有尝试在'%data'中包含'personal_reference'和'title'键? PHP示例设置了全部3个,并且文档不清楚它们是否可选。 – cjm 2012-02-17 22:40:11

+0

@cjm,我试着改变只有PHP的描述,它的工作。 – 2012-02-17 23:01:39

+1

适用标准的HTTP调试技术。使用Wireshark比较请求/响应对。 – daxim 2012-02-18 11:27:25

回答

1

可能你会尝试更换

我%的数据=(说明=> '更新说明');

我的$数据= SOAP ::数据 - >名称(说明=> '更新说明');

我们在处理SOAP API时遇到了类似的问题,并且通过将复杂数据包装到SOAP :: Data中解决了这个问题。所以我希望这会有所帮助。 )

UPDATE:

以前的建议没有帮助:看起来像它确实是SOAP ::精简版的bug,而忽略了 'SOAP-ENC:阵' 在任何WSDL文件的定义。

虽然终于找到了解决方法。这并不漂亮,但作为最后的手段它可能会奏效。

首先,我手动下载从Delcampe网站WSDL文件,保存它变成本地目录,并把它称为...

my $service = SOAP::Lite->service('file://...delcampe.wsdl') 

...因为需要绝对路径。

然后我已经注释掉WSDL updateItem定义中的'arrData line'。

最后,我做了这一点:

my $little_monster = SOAP::Data->name(arrData => 
    \SOAP::Data->value((
    SOAP::Data->name(item => 
     \SOAP::Data->value(
      SOAP::Data->name(key => 'personal_reference'), 
      SOAP::Data->name(value => 'Some Personal Reference')->type('string'), 
     ) 
    ), 
    SOAP::Data->name(item => 
     \SOAP::Data->value(
      SOAP::Data->name(key => 'title'), 
      SOAP::Data->name(value => 'Some Amazing Title')->type('string'), 
     ) 
    ), 
    # ... 
)) 
)->type('ns1:Map'); 

...而且,我承认,成功推出入旷野......

$service->updateItem($key, 123456, $little_monster); 

...这至少可以产生更多或更少的可爱信封。

我真诚地希望至少可以挽救一些可怜的灵魂,使其不至于像在我所做的那样工作。)

+0

这应该起作用 - 我经常被类似地绊倒,请参阅SOAP :: Data的文档以获取如何制作和控制更复杂的数据结构的详细信息(http://search.cpan.org/~mkutter/SOAP-Lite -0.714/lib/SOAP/Data.pod) – Ryley 2012-02-23 18:18:30

+0

它看起来很有前途,但是不一样,“你必须发送项目的数据!”和arrData是空的。 – 2012-02-24 10:27:43

+0

根据您的建议和'SOAP :: Data'文档,我以这种方式构建它:http://pastebin.com/XhyZaM4x。它不起作用。坦率地说,我不认为这会有所帮助,因为我给方法'updateItem'的其他参数是基本的字符串和基本的int,但是当我调试请求信封时,它们正确地形成为XML。那么为什么第三个元素已经被形成为SOAP/XML?这就是'SOAP :: Lite'模块基于WSDL文件规则为我构建它们的思想。 AFAIU – 2012-02-24 22:26:22

相关问题