Net :: Kashflow - 不能使用utf8描述

时间:2016-10-12 14:28:16

标签: perl soap soaplite

我知道这是一个非常古老的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;说明 ..但我不确定如何告诉它不要对该特定字符串进行编码。

任何建议都会非常感激。虽然它不是主要的显示阻止(因为所有数据都在系统中),但是按预期看到项目名称会更好/更容易:)

谢谢!

1 个答案:

答案 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不知道对象的类型时会发挥作用,因为没有人告诉它。我猜测,在你的程序的内容中,序列化Descriptiontypelookup会将其脏手套放入其中。

从这里开始你就是因为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?