Конференция "Сети" » Импорт WSDL для SOAP-клиента не работает! [WinXP]
 
  • 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, которая призвана облегчит мне этот рутинный труд.
    Думаю, доходчиво уточнил :)
 
Конференция "Сети" » Импорт WSDL для SOAP-клиента не работает! [WinXP]
Есть новые Нет новых   [134435   +33][b:0][p:0]