Delphi 7 + SOAP
От: Den1974  
Дата: 27.10.05 21:03
Оценка:
Господа программисты! Пытался ли кто-нить через SOAP послать запрос с комплексным типом и получить ответ от сервера также с комплексным типом? Делаю как сказано в документации, но возвращается все время nil (что посылается в запросе вообще загадка ). Использую Delphi 7 + стандартные SOAP=компоненты. Говорят, что в шестерке эти компоненты были с ошибками, может и в семерке тоже что-то не так работает? Если есть, пришлите примеры работающего кода для сервера и для клиента!
Re: Delphi 7 + SOAP
От: Shtirliz Россия  
Дата: 28.10.05 06:20
Оценка:
Здравствуйте, Den1974, Вы писали:

D>Господа программисты! Пытался ли кто-нить через SOAP послать запрос с комплексным типом и получить ответ от сервера также с комплексным типом? Делаю как сказано в документации, но возвращается все время nil (что посылается в запросе вообще загадка ). Использую Delphi 7 + стандартные SOAP=компоненты. Говорят, что в шестерке эти компоненты были с ошибками, может и в семерке тоже что-то не так работает? Если есть, пришлите примеры работающего кода для сервера и для клиента!


Я работал с SOAP в Delphi. Все замечательно.

Что значит комплексный тип? Покажи что за тип и как ты его передаешь.
... << RSDN@Home 1.2.0 alpha rev. 618>> А в наушниках: Кто спер мою музыку?!!
Дункан Маклауд любил ходить в лес и издеваться над кукушками.
138385660
Re[2]: Delphi 7 + SOAP
От: Den1974  
Дата: 28.10.05 07:06
Оценка:
Здравствуйте, Shtirliz, Вы писали:

S>Я работал с SOAP в Delphi. Все замечательно.


S>Что значит комплексный тип? Покажи что за тип и как ты его передаешь.


Есть скалярные типы (простые типы): integer, byte, string и т.д. А комплексные это например записи. В документации сказано, что для передачи комрлексных (complex) типов нужно создавать потомка от TRematable. Так и делаем:

TCurrency = class(TRemotable)
private
FExchangeRate: double;
FName: string;
public
property ExchangeRate: Double read FExchangeRate write FExchangeRate;
property Name: string read FName write FName;
end;

Потом на сервере пишем функцию, которая принимает в параметрах этот тип и должна обратно его вернуть:

function TCentimeterInch.GetCurrency(const aCurrency: TCurrency): TCurrency;
begin
Result:=aCurrency;
end;

На клиенте делаем запрос:

procedure TForm1.bGetCurrencyClick(Sender: TObject);
var aCurrency, c: TCurrency;
begin
aCurrency:=TCurrency.Create;
{ с:=TCurrency.Create; }
c:=(HTTPRIO1 as ICentimeterInch).GetCurrency(aCurrency);
Caption:=Format('name = %s, excangerate = %f',[c.Name,c.ExchangeRate]);
aCurrency.Free;
end;

после вызова функции переменная "с" равна nil, Даже если раскомментировать вторую строку, все равно после вызова функции переменная "с" равна nil.
Re[3]: Delphi 7 + SOAP
От: Shtirliz Россия  
Дата: 28.10.05 07:31
Оценка:
Здравствуйте, Den1974, Вы писали:

Секции Initialization в сервисе и клиенте покажи...

И там и там должно быть типа такого:

Initialization
  InvRegistry.RegisterInterface(TypeInfo(ICentimeterInch), 'urn:UCentimeterInch-ICentimeterInch', 'utf-8');
  RemClassRegistry.RegisterXSClass(TCurrency, 'urn:UCentimeterInch-ICentimeterInch', 'TCurrency');
... << RSDN@Home 1.2.0 alpha rev. 618>> А в наушниках: Кто спер мою музыку?!!
Дункан Маклауд любил ходить в лес и издеваться над кукушками.
138385660
Re[4]: Delphi 7 + SOAP
От: Den1974  
Дата: 28.10.05 08:00
Оценка:
Здравствуйте, Shtirliz, Вы писали:

S>Здравствуйте, Den1974, Вы писали:


S>Секции Initialization в сервисе и клиенте покажи...


S>И там и там должно быть типа такого:


S>
S>Initialization
S>  InvRegistry.RegisterInterface(TypeInfo(ICentimeterInch), 'urn:UCentimeterInch-ICentimeterInch', 'utf-8');
S>  RemClassRegistry.RegisterXSClass(TCurrency, 'urn:UCentimeterInch-ICentimeterInch', 'TCurrency');
S>



На сервере:
файл CentimeterInchIntf;
initialization
  { Invokable interfaces must be registered }
  InvRegistry.RegisterInterface(TypeInfo(ICentimeterInch));
  
  RemClassRegistry.RegisterXSClass(TCurrency);
  RemClassRegistry.RegisterXSInfo(TypeInfo(TCurrencyArray));


файл CentimeterInchImpl;
initialization
  { Invokable classes must be registered }
  InvRegistry.RegisterInvokableClass(TCentimeterInch);


На клиенте секции инициализации нет.
Re[5]: Delphi 7 + SOAP
От: Shtirliz Россия  
Дата: 28.10.05 09:15
Оценка:
Здравствуйте, Den1974, Вы писали:


А ты делал импорт WSDL?
т.е. что используешь на клиенте? откуда описание интерфеса?
... << RSDN@Home 1.2.0 alpha rev. 618>> А в наушниках: Enigma — Center Of The Sun (Vocals By Sandra)
Дункан Маклауд любил ходить в лес и издеваться над кукушками.
138385660
Re[6]: Delphi 7 + SOAP
От: Den1974  
Дата: 28.10.05 10:49
Оценка:
Здравствуйте, Shtirliz, Вы писали:

S>Здравствуйте, Den1974, Вы писали:



S>А ты делал импорт WSDL?

S>т.е. что используешь на клиенте? откуда описание интерфеса?

описание интерфейса я так понял берется прямо с сервера:

HTTPRIO.WSDLLocation:='http://127.0.0.1/project1.exe/wsdl/ICentimeterInch';
HTTPRIO.Service:='ICentimeterInchservice';
HTTPRIO.Port:=ICentimeterInchPort;


Мне не нужно делать импорт, т.к. и сервер и клиент мой: и там и там я использую модуль CentimeterInchIntf

{ Invokable interface ICentimeterInch }

unit CentimeterInchIntf;

interface

uses InvokeRegistry, Types, XSBuiltIns;

type
  TCurrency = class(TRemotable)
  private
    FExchangeRate: double;
    FName: string;
  public
    property ExchangeRate: Double read FExchangeRate write FExchangeRate;
    property Name: string read FName write FName;
  end;

  TCurrencyArray = array of TCurrency;

  { Invokable interfaces must derive from IInvokable }
  ICentimeterInch = interface(IInvokable)
  ['{36A46AA9-962D-420B-A1A3-6D2F230E7B42}']

    function Cm2Inch(Inch: Double): Double; stdcall;
    function Inch2Cm(Cm: Double): Double; stdcall;
    function GetCurrency(const aCurrency: TCurrency): TCurrency; stdcall;
  end;

implementation

initialization
  { Invokable interfaces must be registered }
  InvRegistry.RegisterInterface(TypeInfo(ICentimeterInch));
  
  RemClassRegistry.RegisterXSClass(TCurrency);
  RemClassRegistry.RegisterXSInfo(TypeInfo(TCurrencyArray));
end.
Re[7]: Delphi 7 + SOAP
От: Shtirliz Россия  
Дата: 28.10.05 13:15
Оценка:
Здравствуйте, Den1974, Вы писали:

D>Здравствуйте, Shtirliz, Вы писали:


S>>Здравствуйте, Den1974, Вы писали:



S>>А ты делал импорт WSDL?

S>>т.е. что используешь на клиенте? откуда описание интерфеса?

D>описание интерфейса я так понял берется прямо с сервера:


D>
D>HTTPRIO.WSDLLocation:='http://127.0.0.1/project1.exe/wsdl/ICentimeterInch';
D>HTTPRIO.Service:='ICentimeterInchservice';
D>HTTPRIO.Port:=ICentimeterInchPort;
D>


D>Мне не нужно делать импорт, т.к. и сервер и клиент мой: и там и там я использую модуль CentimeterInchIntf


Его нужно сделать. Попробуй.
Вот пример моего
Клиент:
  ITradeData = interface(IAppServerSOAP)
    ['{DD6BCD69-BE2F-47A7-9B63-CED004B6711E}']
    ....


Сервер:
  ITradeData = interface(IAppServerSOAP)
    ['{69CDFDAD-9CD6-45A1-8E49-AD09F3D66930}']
    ....



А теперь почувствуй разницу... Или это тока у меня так... Но думаю нет.
Удачи.
... << RSDN@Home 1.2.0 alpha rev. 618>> А в наушниках: Moscow Speed Project — Best of Trance 2004
Дункан Маклауд любил ходить в лес и издеваться над кукушками.
138385660
Re[8]: Delphi 7 + SOAP
От: Den1974  
Дата: 28.10.05 21:52
Оценка:
Здравствуйте, Shtirliz, Вы писали:

S>Его нужно сделать. Попробуй.

S>Вот пример моего
S>Клиент:
S>
S>  ITradeData = interface(IAppServerSOAP)
S>    ['{DD6BCD69-BE2F-47A7-9B63-CED004B6711E}']
S>    ....
S>


S>Сервер:

S>
S>  ITradeData = interface(IAppServerSOAP)
S>    ['{69CDFDAD-9CD6-45A1-8E49-AD09F3D66930}']
S>    ....
S>


S>А теперь почувствуй разницу... Или это тока у меня так... Но думаю нет.

S>Удачи.

Сделал импорт, получил файл


unit ICentimeterInch1;

interface

uses InvokeRegistry, SOAPHTTPClient, Types, XSBuiltIns;

type

  TCurrency            = class;                 { "urn:CentimeterInchIntf" }

  TCurrency = class(TRemotable)
  private
    FExchangeRate: double;
    FName: string;
  public
    property ExchangeRate: Double read FExchangeRate write FExchangeRate;
    property Name: string read FName write FName;
  end;

  ICentimeterInch = interface(IInvokable)
  ['{09FE3389-9018-EA11-C830-E3BDFBB2B4C4}']
    function  Cm2Inch(const Inch: Double): Double; stdcall;
    function  Inch2Cm(const Cm: Double): Double; stdcall;
    function  GetCurrency(const aCurrency: TCurrency): TCurrency; stdcall;
  end;

function GetICentimeterInch(UseWSDL: Boolean=System.False; Addr: string=''; HTTPRIO: THTTPRIO = nil): ICentimeterInch;


implementation

function GetICentimeterInch(UseWSDL: Boolean; Addr: string; HTTPRIO: THTTPRIO): ICentimeterInch;
const
  defWSDL = 'http://localhost/project1.exe/wsdl/ICentimeterInch';
  defURL  = 'http://localhost/project1.exe/soap/ICentimeterInch';
  defSvc  = 'ICentimeterInchservice';
  defPrt  = 'ICentimeterInchPort';
var
  RIO: THTTPRIO;
begin
  Result := nil;
  if (Addr = '') then
  begin
    if UseWSDL then
      Addr := defWSDL
    else
      Addr := defURL;
  end;
  if HTTPRIO = nil then
    RIO := THTTPRIO.Create(nil)
  else
    RIO := HTTPRIO;
  try
    Result := (RIO as ICentimeterInch);
    if UseWSDL then
    begin
      RIO.WSDLLocation := Addr;
      RIO.Service := defSvc;
      RIO.Port := defPrt;
    end else
      RIO.URL := Addr;
  finally
    if (Result = nil) and (HTTPRIO = nil) then
      RIO.Free;
  end;
end;


initialization
  InvRegistry.RegisterInterface(TypeInfo(ICentimeterInch), 'urn:CentimeterInchIntf-ICentimeterInch', 'utf-8');
  InvRegistry.RegisterDefaultSOAPAction(TypeInfo(ICentimeterInch), 'urn:CentimeterInchIntf-ICentimeterInch#%operationName%');
  RemClassRegistry.RegisterXSClass(TCurrency, 'urn:CentimeterInchIntf', 'TCurrency');

end.


Теперь беру интерфейсы от сюда. Ничего не изменилось.
Ты не мог бы кинуть мне на мыло ( samara_den@mail.ru ) исходнички для сервера и клиента (так, чтобы просто перекомпилить и работало)? Я бы наверное сам разобрался.
Re[9]: Delphi 7 + SOAP
От: Den1974  
Дата: 30.10.05 21:24
Оценка:
Немного помучавшись, все таки нашел в чем ошибка:
сделал тот же пример на Delphi 2005 и все пошло! Это ошибка Delphi 7. Точнее сервера, создаваемого на Delphi 7. Потому что клиент, сделанный на Delphi 7 работает с сервером, сделанном на Delphi 2005.
Потом даже нашел кое-что по этому поводу: http://webservices.matlus.com/scripts/webservices.dll
Спасибо, за поддержку.
Re[10]: Delphi 7 + SOAP
От: Shtirliz Россия  
Дата: 31.10.05 09:57
Оценка:
Здравствуйте, Den1974, Вы писали:

D>Немного помучавшись, все таки нашел в чем ошибка:

D>сделал тот же пример на Delphi 2005 и все пошло! Это ошибка Delphi 7. Точнее сервера, создаваемого на Delphi 7. Потому что клиент, сделанный на Delphi 7 работает с сервером, сделанном на Delphi 2005.
D>Потом даже нашел кое-что по этому поводу: http://webservices.matlus.com/scripts/webservices.dll
D>Спасибо, за поддержку.

Нема за шо...

То что ты сделал на Delphi 2005 это, конечно, хорошо, но все прекрасно работает и в D7.
Извини исходник не могу выслать ибо проект был комерческий и на старом месте работы.
И мы там еще с IIS игрались в плане настроек в плане безопасности.

Одним словом, удачи.
... << RSDN@Home 1.2.0 alpha rev. 618>> А в наушниках: Linkin Park — In the end
Дункан Маклауд любил ходить в лес и издеваться над кукушками.
138385660
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.