我知道这是一个非常古老的Perl模块(自上次更新以来大约5年前)。我发现它对我正在做的项目很有用,它需要在Perl中。我没有从下往上开始,而是发现这对基础知识很有帮助。我已经修好了一些错误 - 但是这个我无法弄清楚
有问题的模块是:https://github.com/simoncozens/Net-KashFlow
问题的一个示例用法是:
my $kf = Net::KashFlow->new(username => q|foo@bar.com|, password => "xxxx" );
my $i = $kf->create_invoice({
CustomerReference => "0123-1111111", CustomerID => 50108952,
CurrencyCode => "EUR"
}) || die $!;
$i->add_line({
Quantity => 1,
Description => "íéó foo bar test",
Rate => 10,
VatAmount => 4,
VatRate => 0,
CurrencyCode => "GBP"
});
此项目已添加,但"说明"值转换为:
7enzIGZvbyBiYXIgdGVzdA ==
如果使用普通的a-z 0-9,它可以正常工作(并正确显示)。问题似乎是它编码到base64,然后在另一端没有正确解码。我的猜测是,KashFlow不会去修复"这个,所以它真的需要这样做。我对SOAP :: Lite模块并不是很熟悉(同样,它似乎是一个非常古老的模块!),但这就是它的用途。
这是我认为涉及添加新的"线"到发票:
InsertInvoiceLine => {
endpoint => 'https://securedwebapp.com/api/service.asmx',
soapaction => 'KashFlow/InsertInvoiceLine',
namespace => 'KashFlow',
parameters => [
SOAP::Data->new(name => 'UserName', type => 'xsd:string', attr => {}),
SOAP::Data->new(name => 'Password', type => 'xsd:string', attr => {}),
SOAP::Data->new(name => 'InvoiceID', type => 'xsd:int', attr => {}),
SOAP::Data->new(name => 'InvLine', type => 'tns:InvoiceLine', attr => {}),=> {})
], # end parameters
}, # end InsertInvoiceLine
您可以在此处查看结构:
https://securedwebapp.com/api/service.asmx?op=InsertInvoiceLine
在研究了这个之后,有人建议你告诉 SOAP :: Lite 到而不是将utf8转换成base64,使用(我假设),如:
结构是:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<InsertInvoiceLine xmlns="KashFlow">
<UserName>string</UserName>
<Password>string</Password>
<InvoiceID>int</InvoiceID>
<InvLine>
<Quantity>decimal</Quantity>
<Description>string</Description>
<Rate>decimal</Rate>
<ChargeType>int</ChargeType>
<VatRate>decimal</VatRate>
<VatAmount>decimal</VatAmount>
<ProductID>int</ProductID>
<Sort>int</Sort>
<ProjID>int</ProjID>
<LineID>int</LineID>
<ValuesInCurrency>integer</ValuesInCurrency>
</InvLine>
</InsertInvoiceLine>
</soap:Body>
</soap:Envelope>
看起来像 Body&gt; InsertInvoiceLine&gt; InvLine&gt;说明 ..但我不确定如何告诉它不要对该特定字符串进行编码。
任何建议都会非常感激。虽然它不是主要的显示阻止(因为所有数据都在系统中),但是按预期看到项目名称会更好/更容易:)
谢谢!
答案 0 :(得分:2)
我认为这可能SOAP::Lite在认为它们不是ASCII的特定子集时决定将事物转换为base64。您将在SOAP::Serializer
中的 SOAP / Lite.pm 中找到此启发式:
$self->typelookup({
'base64Binary' =>
[10, sub {$_[0] =~ /[^\x09\x0a\x0d\x20-\x7f]/ }, 'as_base64Binary'],
'zerostring' =>
[12, sub { $_[0] =~ /^0\d+$/ }, 'as_string'],
... many other types ...
'string' =>
[100, sub {1}, 'as_string'],
});
当SOAP :: Lite不知道对象的类型时会发挥作用,因为没有人告诉它。我猜测,在你的程序的内容中,序列化Description
和typelookup
会将其脏手套放入其中。
从这里开始你就是因为SOAP :: Lite并不好玩。我会先点击一下SOAP :: Lite,看看你能追踪什么。将 SOAP / Lite.pm 文件复制到某处,并将该位置放在@INC
中。这样你就不会乱用原始文件。
如果你从不想要base64,它可能就像在 typelookup 中删除那一行一样简单,虽然声明Description
类型更合适(但也是一只兔子&#39;可能的工作漏洞。当你正确修复时,快速修复可以站立。
还有Perlmonk的冥想How to convince SOAP::Lite to return UTF-8 data in responses as UTF-8?。