-
UnDISCOvery (22.12.08 20:32) [0]Привет, Мастера!
Задача у меня банальная - написать клиента для SOAP.
Прочитал доки, факи - создал тестовый сервер и клиент, там все отлично работало. Думал, что разобрался и приступил к реализации. Вот тут-то и натолкнулся на трудности...
Мне предоставили wsdl-файл (http://www.airts.ru/webservices/2009/01/ATS_RailReservationRQ.wsdl).
Сгенерировал с помощью него интерфейсный модуль.
Пробую отправить данные на сервер - он не может даже входные параметры корректно создать!
--- кусок кода. начало ---
procedure TfmATS_RailReservClient.btnTestClick(Sender: TObject);
var
TmpMsgHeader : MessageHeader;
TmpRailAvailRQ : ATS_RailAvailRQ;
TmpRailAvailRS : ATS_RailAvailRS;
begin
TmpMsgHeader := MessageHeader.Create;
TmpMsgHeader.SessionId := '1234567890';
TmpMsgHeader.MessageData.TimeToLive.AsDateTime := Now - 1; { !!! ТУТ Access Violation !!!}
TmpRailAvailRQ := ATS_RailAvailRQ.Create;
TmpRailAvailRS := (HTTPRIO1 as RailReservationRQPortType).RailAvailRQ(TmpMsgHeader,TmpRailAvailRQ);
memoRailRS.Lines.Text := DateTimeToStr(TmpMsgHeader.MessageData.TimeToLive.AsDateTime);
end;
--- кусок кода. конец ---
TmpMsgHeader - является первым входным параметров для вэб-сервиса. Как видно из примера SessionId назначается нормально, но MessageData.TimeToLive не назначается.
Таким образом и в остальном: простые параметры доступны, составные - нет!
Лезу в сгенерированный модуль - там интересная штука: деструкторы для составных(вложенных) типов есть, а конструкторов нет. Поэтому они все nil, поэтому и AV в итоге.
Как быть? Неужели все такие классы руками прописывать надо? О ужас!
Или может что-то настроить в WSDL Importer, а?
Помогите!
Заранее, спасибо. -
Palladin © (23.12.08 06:54) [1]
> а конструкторов нет
Кто это сказал? Есть. У родителя.
> Поэтому они все nil
да ну конечно... -
Плохиш © (23.12.08 12:00) [2]
> UnDISCOvery (22.12.08 20:32)
>
>
> Как быть?
В спецификации языка делфи написано, что все объекты должны быть созданы перед использованием. -
UnDISCOvery (24.12.08 15:25) [3]2 Palladin:
У какого родителя? Если у первичного объекта, то да - конечно есть.
Вот он в примере -> TmpMsgHeader := MessageHeader.Create;
Но в том то вся и штука, что это конструктор именно родителя, а не собственный переопределенный.
---
MessageHeader = class(TSOAPHeader)
private
FFrom: From;
FTo_: To_;
FCPAId: CPAId;
FCPAKey: non_empty_string;
FCPAKey_Specified: boolean;
FConversationId: ConversationId;
FSessionId: non_empty_string;
FSessionId_Specified: boolean;
FService: Service;
FAction: Action;
FMessageData: MessageData;
FDuplicateElimination: WideString;
FDuplicateElimination_Specified: boolean;
procedure SetCPAKey(Index: Integer; const Anon_empty_string: non_empty_string);
function CPAKey_Specified(Index: Integer): boolean;
procedure SetSessionId(Index: Integer; const Anon_empty_string: non_empty_string);
function SessionId_Specified(Index: Integer): boolean;
procedure SetDuplicateElimination(Index: Integer; const AWideString: WideString);
function DuplicateElimination_Specified(Index: Integer): boolean;
public
destructor Destroy; override;
published
property From: From Index (IS_REF) read FFrom write FFrom;
property To_: To_ Index (IS_REF) read FTo_ write FTo_;
property CPAId: CPAId Index (IS_REF) read FCPAId write FCPAId;
property CPAKey: non_empty_string Index (IS_OPTN) read FCPAKey write SetCPAKey stored CPAKey_Specified;
property ConversationId: ConversationId Index (IS_REF) read FConversationId write FConversationId;
property SessionId: non_empty_string Index (IS_OPTN) read FSessionId write SetSessionId stored SessionId_Specified;
property Service: Service Index (IS_REF) read FService write FService;
property Action: Action Index (IS_REF) read FAction write FAction;
property MessageData: MessageData Index (IS_REF) read FMessageData write FMessageData;
property DuplicateElimination: WideString Index (IS_OPTN) read FDuplicateElimination write SetDuplicateElimination stored DuplicateElimination_Specified;
end;
---
Как видно - деструктор есть, а конструктора нет.
---
destructor MessageHeader.Destroy;
begin
FreeAndNil(FFrom);
FreeAndNil(FTo_);
FreeAndNil(FService);
FreeAndNil(FMessageData);
inherited Destroy;
end;
---
То есть эти "встроенные" объекты автоматом уничтожаются, но не создаются!!!
Почему так? Почему импортер генерит такой код?
---
> Поэтому они все nil
да ну конечно...
Не верите? Проверьте сами ... wsdl я выложил -
UnDISCOvery (24.12.08 15:34) [4]2 Плохиш:
>> Как быть?
>В спецификации языка делфи написано, что все объекты должны быть >созданы перед использованием.
Да, спецификацию я знаю... не первый год уже.
Мой вопрос не в том - как самому создать объект перед использованием и для чего это нужно, а в том - почему это не делает автоматически утилита WSDL Importer, которая призвана облегчит мне этот рутинный труд.
Думаю, доходчиво уточнил :)