Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 05.09.2011, 16:15
Servy Servy вне форума
Прохожий
 
Регистрация: 05.09.2011
Сообщения: 1
Репутация: 10
По умолчанию Отправка Soap Headers

Возникла необходимость написать клиент к одному SOAP-сервису. От авторов сервиса пришел пример, как должен выглядеть запрос, он приведен ниже. Я заменил url сервиса заказчика на "http://serviceurl/", ибо он длинный и не должен быть доступен широкой публике:

Код:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://serviceurl/" xmlns:ns2="redeemVoucher">
  <SOAP-ENV:Header>
    <ns2:Authorization>Basic b2N0b2JlcjoxMjM0</ns2:Authorization>
  </SOAP-ENV:Header>
  <SOAP-ENV:Body>
    <ns1:redeemVoucher>
      <partner_id>26538</partner_id>
      <voucher_id>9910000000980</voucher_id>
      <timeout>20</timeout>
      <transaction_data>Some data here
 	</transaction_data>
    </ns1:redeemVoucher>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

В Делфи я экспортнул wsdl'ку. Header в wsdl'ке не описан. Прочитав:

http://docwiki.embarcadero.com/RADSt...g_SOAP_Headers

Я написал следующий код:

Код:
TAuthHeader = class(TSOAPHeader)
private
  FAuthorization: string;
published
  property Authorization: string read FAuthorization write FAuthorization;
end;

// ...

initialization
  { VoucherService }
  InvRegistry.RegisterInterface(TypeInfo(VoucherService), 'http://serviceurl/', 'UTF-8'); // сгенерировано делфи
 
  InvRegistry.RegisterHeaderClass(TypeInfo(VoucherService), TAuthHeader, 'Authentification', '');
  RemClassRegistry.RegisterSerializeOptions(TAuthHeader, [xoSimpleTypeWrapper]);

При вызове передаю заголовок следующим образом:

Код:
function SendRedeemVoucherW(PartnerId: PWideChar; VoucherId: PWideChar;
                           Timeout: Integer;
                           TransactionData: PWideChar): HRESULT;
var
  Headers: ISOAPHeaders;
  H: TAuthHeader;
begin
  LogWrite('redeemVoucher has been called', Standart);

  Headers := PartnerVoucherService as ISOAPHeaders;

  H := TAuthHeader.Create;
  H.Authorization := 'Basic b2N0b2JlcjoxMjM0';
  Headers.OwnsSentHeaders := True;
  Headers.Send(H);

  Result := PartnerVoucherService.redeemVoucher(PartnerId, VoucherId,
                                               Timeout, TransactionData);


При этом, Делфи отправляет следующий запрос (я отформатировал xml, чтобы удобнее было читать):

Код:
POST / HTTP/1.1
SOAPAction: ""
Content-Type: text/xml; charset="utf-8"
User-Agent: CodeGear SOAP 1.3
Host: localhost:8333
Content-Length: 652
Connection: Keep-Alive
Cache-Control: no-cache

<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <SOAP-ENV:Header>
    <NS1:TAuthHeader xmlns:NS1="urn:uVoucher">
      <NS1:Authorization>Basic b2N0b2JlcjoxMjM0</NS1:Authorization>
    </NS1:TAuthHeader>
  </SOAP-ENV:Header>
  <SOAP-ENV:Body>
    <redeemVoucher xmlns="http://services.partnergw.servop.ru/">
      <partner_id xmlns="">26538</partner_id>
      <voucher_id xmlns="">9910000000980</voucher_id>
      <timeout xmlns="">10</timeout>
      <transaction_data xmlns="">Some data</transaction_data>
    </redeemVoucher>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Сервис возвращает ошибку авторизации. Собственно вопрос - как передать soap-header так, как этого ждет сервис:

Код:
<SOAP-ENV:Header>
	<ns2:Authorization>Basic b2N0b2JlcjoxMjM0</ns2:Authorization>
</SOAP-ENV:Header>

А не так, как это происходит при использовании вышеприведенного кода, написанного (ну, я старался ^_^) согласно справке:

Код:
<SOAP-ENV:Header>
	<NS1:TAuthHeader xmlns:NS1="urn:uVoucher">
		<NS1:Authorization>Basic b2N0b2JlcjoxMjM0</NS1:Authorization>
 	</NS1:TAuthHeader>
</SOAP-ENV:Header>


Есть злобный вариант - просто открыть сокет и писать туда все руками так, как этого ждет сервис. Но формирование SOAP запроса руками видится мне костылем, и убивает всю "идею" соапа.

Полезные ссылки по теме тоже приветствуются.

P.S. Мои знания технологии SOAP, и тем более особенностей ее реализации в Делфи далеки до идеала.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 11:30.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter