Модуль SOAP::Lite Perl отправляет неправильное пространство имен конверта SOAP

У меня проблемы с написанием SOAP/XML-клиента для общения с API, предоставленным компанией Domainbox. Я пишу клиент на Perl, используя модуль / библиотеку SOAP::Lite. Я получаю следующее сообщение об ошибке:

Возможное несоответствие версии SOAP: пространство имен конверта http://schemas.xmlsoap.org/soap/envelope/ было неожиданным. Ожидая http://www.w3.org/2003/05/soap-envelope.

Это связано с тем, что библиотека отправляет конверт SOAP с использованием пространства имен SOAP 1.1, а сервер ожидает SOAP 1.2.

Но я не могу найти решение, я попытался явно установить $soap->soapversion('1.2'); в объекте SOAP::Lite, но это влияет только на конверт, полученный в ответном сообщении, но не на конверт, отправленный клиентом.

Сервер работает на ASP.net и, похоже, не хочет принимать сообщения SOAP версии 1.1.

Запрашивая метод soapversion() по умолчанию, он возвращает версию 1.1, а когда я изменяю его на 1.2, он возвращает 1.2, но внутренне он явно игнорирует это где-то.

WSDL, похоже, не определяет xmlns:soap или xmlns:soap12 должным образом, но SOAP::Lite также не использует эти пространства имен. Я хотел бы предоставить ссылку, но мне не разрешено размещать более двух здесь.

Я также пытался использовать метод service() SOAP::Lite, но это не имело никакого значения.

Вот код, который я использую:

#!/usr/bin/perl -w
use strict;
use SOAP::Lite;
use Data::Dumper;

### API Info
my $reseller = 'Removed';
my $username = 'Removed';
my $password  = 'Removed';

my $soap = SOAP::Lite->new(proxy => 'https://sandbox.domainbox.net/');
$soap->default_ns('https://sandbox.domainbox.net/');
$soap->soapversion('1.2');

my $header = SOAP::Header->new->attr({xmlns => 'https://sandbox.domainbox.net/'});

my $body = SOAP::Data->name('CheckDomainAvailability' => \SOAP::Data->value(
            SOAP::Data->name('AuthenticationParameters' => \SOAP::Data->value(
                SOAP::Data->name('Reseller' => $reseller),
                SOAP::Data->name('Username' => $username),
                SOAP::Data->name('Password' => $password),
            )
        )
    )
);

$soap->on_action( sub { "https://sandbox.domainbox.net/" });
my $som = $soap->call('',
$header,
$body
);

die $som->faultstring if ($som->fault);
print $som->result, "\n";

#print Dumper($som);

Дополнительно:

Атрибут xmlns:soap в конверте имеет значение http://schemas.xmlsoap.org/soap/envelope независимо от настройки soapversion в классе. Я думаю, что это ошибка в модуле Perl или что-то странное в WSDL, которое его вызывает. Вот WSDL: http://sandbox.domainbox.net/?WSDL

Сообщение запроса XML:

<?xml version="1.0" encoding="UTF-8"?><Envelope 
soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org
/2001/XMLSchema-instance"><Header><c-gensym3 
xmlns="https://sandbox.domainbox.net/" /></Header><Body><DomainboxAPI 
xmlns="https://sandbox.domainbox.net/"><CheckDomainAvailability>
<AuthenticationParameters><Reseller 
xsi:type="xsd:string">Removed</Reseller><Username 
xsi:type="xsd:string">Removed</Username><Password 
xsi:type="xsd:string">Removed</Password></AuthenticationParameters>
</CheckDomainAvailability></DomainboxAPI></Body></Envelope>

Ответное сообщение XML:

<?xml version="1.0" encoding="utf-8"?><soap:Envelope 
xmlns:soap="http://www.w3.org/2003/05/soap-envelope" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Header>
<soap12:Upgrade xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:SupportedEnvelope qname="soap12:Envelope" 
xmlns:soap12="http://www.w3.org/2003/05/soap-envelope"/></soap12:Upgrade>
</soap:Header><soap:Body><soap:Fault><soap:Code>
<soap:Value>soap:VersionMismatch</soap:Value></soap:Code><soap:Reason>
<soap:Text xml:lang="en">Possible SOAP version mismatch: Envelope 
namespace  was unexpected. Expecting http://www.w3.org/2003/05/soap-
envelope.</soap:Text></soap:Reason><soap:Detail /></soap:Fault>
</soap:Body></soap:Envelope>

Обновить:

Спасибо, Бородин, ты был на месте. Модуль SOAP::Lite, похоже, не передает параметр soapversion объекту SOAP::Lite::Serializer. Теперь я использую следующий код для инициализации объекта SOAP, и он отлично работает.

my $soap = SOAP::Lite->new(proxy => 'https://sandbox.domainbox.net/');
$soap->default_ns('https://sandbox.domainbox.net/');
$soap->soapversion('1.2');
$soap->serializer->soapversion('1.2');

Я должен отметить, что мне пришлось также настроить свой код в соответствии с форматом XML, требуемым для Domainbox, но сейчас я получаю действительный ответ.

Моя единственная проблема сейчас заключается в том, как обращаться с хеш-ссылкой, которую SOAP::Lite::SOM возвращает в результате сообщения. Я думаю, что это требует отдельного вопроса, хотя.

1 ответ

Ответ на мой вопрос дал Бородин. Правильный код - использовать метод soapversion как для объекта SOAP::Lite, так и для объекта SOAP::Lite::Serializer. Вот рабочий пример:

my $soap = SOAP::Lite->new(proxy => 'https://sandbox.domainbox.net/');
$soap->default_ns('https://sandbox.domainbox.net/');
$soap->soapversion('1.2');
$soap->serializer->soapversion('1.2');
Другие вопросы по тегам