SOAP: неверный запрос HTTP

После запроса SOAP я получаю ниже ошибки.

код ошибки: HTTP, строка ошибки: неверный запрос

Это плохо сформированное сообщение?

try{
    $client = new SoapClient("http://ip_add/something.asmx?WSDL", array("trace" => true, 'exceptions' => 1));

    $params = new \SoapVar('<?xml version="1.0" encoding="utf-8"?>
                <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
                <soap:Body>
                    <RemittanceService xmlns="http://tempuri.org/">
                    <CreditTxnMessage xmlns="http://my_url">
                    <Corporate_UID xmlns="">66666</Corporate_UID>
                    <Mandate_Type xmlns="">P</Mandate_Type>
                    <MICR_No xsi:nil="true" xmlns="" />
                    <Instrument_No xsi:nil="true" xmlns="" />
                    <Remitter_Address1 xmlns="">285 enfiled pl</Remitter_Address1>
                    <Remitter_Address2 xmlns="">mississauga</Remitter_Address2>
                    <Remitter_Address3 xmlns="">16y2n4</Remitter_Address3>
                    <Remitter_Country xmlns="">Canada</Remitter_Country>
                    <Remitter_ZIP_Code xsi:nil="true" xmlns="" />
                    <Remitter_EmailID xsi:nil="true" xmlns="" />
                    <Remitter_Contact_No xmlns="" />
                    <Beneficiary_ZIP_Code xsi:nil="true" xmlns="" />
                    <Beneficiary_EmailID xsi:nil="true" xmlns="" />
                    <Beneficiary_Contact_No xmlns="" />
                    <Beneficiary_Bank_Name xmlns="">PNB</Beneficiary_Bank_Name>
                    </CreditTxnMessage>
                    </RemittanceService>
                </soap:Body>
                </soap:Envelope>', XSD_ANYXML);

    $result = $client->__soapCall('RemittanceService', array($params));
    highlight_string($client->__getLastRequest());
}
catch(SoapFault $fault){
    die("SOAP Fault:<br />fault code: {$fault->faultcode}, fault string: {$fault->faultstring}");
}

Я не знаю, что здесь не так.

Трассировка стека

SoapFault exception: [HTTP] Bad Request in /var/www/mtes/public_html/application/controllers/bank_api_pnb.php:146
Stack trace:
#0 [internal function]: SoapClient->__doRequest('<?xml version="...', 'http://124.124....', 'http://tempuri....', 1, 0)
#1 /var/www/mtes/public_html/application/controllers/bank_api_pnb.php(146): SoapClient->__soapCall('RemittanceServi...', Array)
#2 [internal function]: Bank_api_pnb->test()
#3 /var/www/mtes/public_html/system/core/CodeIgniter.php(359): call_user_func_array(Array, Array)
#4 /var/www/mtes/public_html/index.php(220): require_once('/var/www/mtes/p...')
#5 {main}

Ответ 1

Вся суть SoapClient - конвертировать вызовы в xml; поэтому вы не должны делать это вручную. Вместо этого попробуйте:

try {
    $client = new SoapClient("http://ip_add/something.asmx?WSDL", array("trace" => true, 'exceptions' => 1));

    $result = $client->RemittanceService(array(
            'CreditTxnMessage' => array(
                    'Corporate_UID' => 66666,
                    'Mandate_Type' => 'P',
                    'MICR_No' => null,
                     /* you get the idea */
                    'Beneficiary_Contact_No' => '',
                    'Beneficiary_Bank_Name' => 'PNB'
            )
    ));

    highlight_string($client->__getLastRequest());
}
catch(SoapFault $fault){
    die("SOAP Fault:<br />fault code: {$fault->faultcode}, fault string: {$fault->faultstring}");
}

Точный формат параметров и их имена будут указаны в WSDL.

Ответ 2

Обычно ответ Bad Request на запрос SOAP возвращается, когда сообщение не находится в хорошем формате (недопустимый заголовок, тело,..), и поэтому документ не может быть проанализирован. Прежде всего попытайтесь удалить объявление XML-версии из SoapVar и посмотреть, исправляет ли она проблему (удалите строку ниже):

<?xml version="1.0" encoding="UTF-8"?> 

В качестве альтернативы вы всегда можете проверить свои запросы на мыло в таких инструментах, как SoapUI, чтобы убедиться, что они работают, а затем заполнить ваш код. Если это не работает в SoapUI, это значит, что с запросом что-то не так. Попробуйте пересмотреть WS и убедитесь, что вы отправляете все в правильном формате (например, возможно, вам нужно пройти аутентификацию? SoapHeader?..)

Ответ 3

Я не знаком с PHP, но попробую это.

$Request = '<RemittanceService xmlns="http://tempuri.org/">
                    <CreditTxnMessage xmlns="http://my_url">
                    <Corporate_UID xmlns="">66666</Corporate_UID>
                    <Mandate_Type xmlns="">P</Mandate_Type>
                    <MICR_No xsi:nil="true" xmlns="" />
                    <Instrument_No xsi:nil="true" xmlns="" />
                    <Remitter_Address1 xmlns="">285 enfiled pl</Remitter_Address1>
                    <Remitter_Address2 xmlns="">mississauga</Remitter_Address2>
                    <Remitter_Address3 xmlns="">16y2n4</Remitter_Address3>
                    <Remitter_Country xmlns="">Canada</Remitter_Country>
                    <Remitter_ZIP_Code xsi:nil="true" xmlns="" />
                    <Remitter_EmailID xsi:nil="true" xmlns="" />
                    <Remitter_Contact_No xmlns="" />
                    <Beneficiary_ZIP_Code xsi:nil="true" xmlns="" />
                    <Beneficiary_EmailID xsi:nil="true" xmlns="" />
                    <Beneficiary_Contact_No xmlns="" />
                    <Beneficiary_Bank_Name xmlns="">PNB</Beneficiary_Bank_Name>
                    </CreditTxnMessage>
                    </RemittanceService>';
$result = $client->__doRequest($Request, "http://ip_add/something.asmx", "RemittanceService",  soap_1_2, 0);

Ответ 4

Я не уверен, как работает SoapVar, но я бы посоветовал не передавать в raw XML в SoapClient. Я бы попытался воссоздать структуру XML в массивах PHP (это болезненно, я знаю), тем более, что XML отображается в трассировке стека:

$params = array(
    "RemittanceService" => array("xmlns"=>"http://tempuri.org/", "_" => array(
        "CreditTxnMessage" => array("xmlns" => "http://my_url", "_" => array(
            "Corporate_UID" => array("xmlns" => "", "_" => 66666),
            "Mandate_Type" => array("xmlns" => "", "_" => "P"),
            "MICR_No" => array("xsi:nil" => "true", "xmlns" => ""),
            // and so on...
        ))
    ))
);

Кроме того, вы должны, вероятно, указать версию SOAP (SOAP_1_1 или SOAP_1_2) в конструкторе SOAPClient:

$client = new SoapClient("http://ip_add/something.asmx?WSDL", array('soap_version' => SOAP_1_2, "trace" => true, 'exceptions' => 1));

Кроме того, массив аргументов в __soapCall() довольно разборчив в отношении форматирования. Попробуйте следующее:

$result = $client->__soapCall('RemittanceService', array('parameters' => $params));

Или даже:

$result = $client->__soapCall('RemittanceService', $params);

Я в основном догадываюсь о том, в чем проблема, поэтому это не очень тщательное решение. Вы также можете попробовать искать в другом месте на SO. Например, этот ответ использует SoapVar.