Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Internet (https://www.clubdelphi.com/foros/forumdisplay.php?f=3)
-   -   Como leer un TRemotable que proviene de un webservice (https://www.clubdelphi.com/foros/showthread.php?t=75437)

apicito 23-08-2011 09:50:07

Como leer un TRemotable que proviene de un webservice
 
Estoy utilizando Delphi2010. Importo un wsdl a través de WsdlImporter que me crea una unit Consolidacion.
En ella se crean los métodos:
Código Delphi [-]
  ConsolidacionWS = interface(IInvokable)
  ['{8796BA36-EF66-FC3D-8199-9C6A7C27E916}']
    function  getEstado(const entidad: string): string; stdcall;
    function  getListaRegistros(const entidad: string): Array_Of_registroBean; stdcall;
    function  resetFechaRegistrosEntrada: string; stdcall;
  end;

function GetConsolidacionWS(UseWSDL: Boolean=System.False; Addr: string=''; HTTPRIO: THTTPRIO = nil): ConsolidacionWS;
El parámetro Addr de la función GetConsolidacionWS se carga durante la implementación, en el supuesto de que sea vacio, con la dirección del webservice
donde registroBean es una Tremotable:
Código Delphi [-]
  registroBean = class(TRemotable)
  private
    Fasunto: string;
    Fasunto_Specified: boolean;
    FcorreoElectronico: string;
    ......

Array_Of_registroBean = array of registroBean;
Intento leer la respuesta desde otra unidad donde importo Consolidacion:
Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
var Lista     : Consolidacion.Array_Of_registroBean;
    Registro  : Consolidacion.registroBean;
    Asunto    : string;
begin
  Setlength(Lista, 3);
  Lista := Consolidacion.GetConsolidacionWS.getListaRegistros('004');
  for Registro in Lista do begin
    Asunto := Registro.asunto;
    Memo1.Lines.Add('====================================');
    Memo1.Lines.Add(Asunto);
  end;
end;
Esto no funciona y no sé como debo capturar los valores que me devuelve el webservice.
Alguien me puede ayudar?.

egostar 24-08-2011 03:54:10

Cita:

Empezado por apicito (Mensaje 409927)
Esto no funciona y no sé como debo capturar los valores que me devuelve el webservice.
Alguien me puede ayudar?.

Puedes ver éste enlace, espero que te ayude a comprender el uso de los TRemotable

Saludos

apicito 24-08-2011 09:58:49

El ejemplo, hasta donde yo entiendo, no me sirve, debe de estar hecho con una versión anterior de Delphi. Yo estoy usando la versión 2010 y la funcion me devuelve un array de TRemotables
Código:

function  getListaRegistros(const entidad: string): Array_Of_registroBean; stdcall;
y no un widestring conteniendo un xml como en el ejemplo. Supongo que en esta versión de Delphi este trabajo ya lo hace la unidad que genera el WSDLImporter.
Mi problema es que no consigo recorrer ese Array_Of_registroBean. He probado multiples opciones como la que aparece en el último trozo de código de mi anterior mensaje y esta:
Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject); 
var Lista     : Array_Of_registroBean;
     Asunto    : string; 
begin   
   Setlength(Lista, 30);
   Lista := Consolidacion.GetConsolidacionWS.getListaRegistros('004');
   Asunto := Lista[0].asunto;
   Memo1.Lines.Add('====================================');
   Memo1.Lines.Add(Asunto);
end;
Pero ninguna me funciona. Parece como si estuviese vacío.
Gracias de todos modos por tu información y sigo esperando a que alguien me sugiera alguna posible solución.
Un saludo.

egostar 26-08-2011 04:23:41

Hola

he hecho una pequeña prueba para leer un Array of TRemotable y me funciona perfectamente.

Código Delphi [-]

procedure TForm1.Button1Click(Sender: TObject);
var
  Lista: IListaArray;
  i: Integer;
begin
  Consultas := GetIwsConsulta(true,'',nil);
  Lista := Consultas.GetArrayoftrRetorno;
  for i := 0 to High(Lista) do
  begin
    memo1.Lines.Add(inttostr(lista[i].ID) + '--->' + lista[i].Descripcion);
  end;
end;

IListaArray está declarado en el webservice así:

Código Delphi [-]

  trRetorno = class(TRemotable)
  private
    FID: Integer;
    FDescripcion: string;
  published
    property ID: Integer  read FID write FID;
    property Descripcion: string read FDescripcion write FDescripcion;
  end;

  IListaArray = array of trRetorno;

Y el resultado es éste:



A menos que tu webservice no esté regresando nada, no veo el problema.

Saludos

PD, estoy utilizando DelphiXE, pero debe funcionar igual con versiones anteriores, lo probaré con mi Turbo Delphi y te comento, además, estoy utilizando el mismo documento que te enlacé, solo le agregué el tipo IListaArray.

egostar 27-08-2011 02:46:56

Confirmado, utilizando Turbo Delphi (Delphi 2006) funciona igual de bien.



Mismo código, utilizando el WSDL Importer de D2006.

Código Delphi [-]

procedure TForm1.Button1Click(Sender: TObject);
var
  Consultas: IwsConsulta;
  Lista: IListaArray;
  i: Integer;
begin
  Consultas := GetIwsConsulta(true,'',nil);
  Lista := Consultas.GetArrayoftrRetorno;
  for i := 0 to High(Lista) do
  begin
    memo1.Lines.Add(inttostr(lista[i].ID) + '--->' + lista[i].Descripcion);
  end;
end;

Si tu webservice es accesible por internet y si puedes envíamelo por mensaje privado y lo checamos.

Saludos.

apicito 27-08-2011 11:07:42

Acabo de enviarte un correo electrónico a través de tu cuenta para que pruebes haber si a ti te funciona.
Yo me he bajado el trial de Delphi XE para probar, por si era un problema de versión, pero tampoco conseguí hacer lo funcionar.
Gracias por el tiempo que le estás dedicando a mi problema.

egostar 27-08-2011 16:55:31

Cita:

Empezado por apicito (Mensaje 410248)
Acabo de enviarte un correo electrónico a través de tu cuenta para que pruebes haber si a ti te funciona.
Yo me he bajado el trial de Delphi XE para probar, por si era un problema de versión, pero tampoco conseguí hacer lo funcionar.
Gracias por el tiempo que le estás dedicando a mi problema.

Hola

Ya he realizado las pruebas y si me regresó 3 registros. Creo que el 'secreto' está en ejecutar la función resetFechaRegistrosEntrada antes de la consulta ya que sin eso regresa una lista vacia. De cualquier forma te muestro el código que usé.

Código Delphi [-]

procedure TForm1.Button1Click(Sender: TObject);
var
  Consultas: ConsolidacionWS;
  Lista: getListaRegistrosResponse;
  i: Integer;
begin
  Consultas := GetConsolidacionWS(true,'',nil);
  memo1.Lines.Add(Consultas.resetFechaRegistrosEntrada);
  Lista := Consultas.getListaRegistros('004');
  for i := 0 to High(Lista) do
  begin
    //:::::::
    memo1.Lines.Add(lista[i].nombre);
    //:::::::
  end;
end;

Y si, con Turbo Delphi no se recupera correctamente el WSDL ya que el protocolo SOAP que se utiliza en esa versión no es compatible con la del webservice.

Saludos

apicito 27-08-2011 17:19:47

Entre tu código y el que yo estaba utilizando existe esta diferencia:
Yo definia Lista como Array_Of_registroBean
Código Delphi [-]
var Lista : Array_Of_registroBean
y tu como:
Código Delphi [-]
var Lista: getListaRegistrosResponse;
A mi no me compila con tu opción ya que no reconoce ese tipo. Como defines este tipo en la unit que produce el WsdlImporter?

egostar 27-08-2011 18:25:47

En el WSDL viene de esta forma

Código Delphi [-]

registroBean         = class;                 { "http://dominio/"[GblCplx] }

getListaRegistrosResponse = array of registroBean;   { "http://dominio/"[Lit][GblCplx] }

  registroBean = class(TRemotable)
  private
    Fasunto: string;
    /........
  published
    property asunto:             string    Index (IS_OPTN or IS_UNQL) read Fasunto write Setasunto stored asunto_Specified;
    /........
  end;

Saludos

apicito 27-08-2011 18:50:57

A mi me genera esto:
Código Delphi [-]
  
registroBean         = class;                 { "http://services.xxxxx/"[GblCplx] }
return                 = class;                 { "http://services.xxxxx/"[Alias] }

  registroBean = class(TRemotable)
  private
    Fasunto: string;
    Fasunto_Specified: boolean;
    FcorreoElectronico: string;
    FcorreoElectronico_Specified: boolean;
y
Código Delphi [-]
Array_Of_registroBean = array of registroBean;
y
Código Delphi [-]
  ConsolidacionWS = interface(IInvokable)
  ['{8796BA36-EF66-FC3D-8199-9C6A7C27E916}']
    function  getEstado(const entidad: string): string; stdcall;
    function  getListaRegistros(const entidad: string): Array_Of_registroBean; stdcall;
    function  resetFechaRegistrosEntrada: string; stdcall;
  end;

function GetConsolidacionWS(UseWSDL: Boolean=System.False; Addr: string=''; HTTPRIO: THTTPRIO = nil): ConsolidacionWS;
Te pego el código completo en un privado.

apicito 27-08-2011 19:03:33

Te ponmgo en un privado el enlace de descarga de mi unit.

apicito 27-08-2011 19:09:17

He sustituido mi ConsolidacionWS1.pas por el que me has enviado y sigue sin funcionar. Hace bien el reseteo de la descarga dando el mensaje: "Base de datos actualizada correctamente" Pero despues no descarga los tres registros.
Ya no sé que puede estar pasando.
Lo Estoy probando con el Delphi XE.

apicito 27-08-2011 20:24:31

Me he dado de cuenta de que están modificando el WS y por esto no coinciden el que yo había importado con el que tu estás importando ahora. Ahora cuando lo importo yo ya se parece al que te sale a ti. De hecho si importas de nuevo verás que ha cambiado.
El lunes intentaré averiguar que es lo que está pasando.
Un par de preguntas:
¿Cuando le das importar lo dejas en automático o seleccionar una version determinada de soap 1.1 o 1.2?
¿En la ultima pantalla dejas marcadas las opciones por defecto o cambias alguna opción?.

egostar 27-08-2011 21:37:08

No creo que hayan cambiado el wservice, así es como lo resuelve mi Turbo Delphi, lo que me indica que el problema es con el protocolo del SOAP, en mi Delphi XE dejo en Automático la importación y las opciones de la ultima pantalla en los 'default'.

He ejecutado tu proyecto y me funciona correctamente, si no puedes ejecutar ese mismo proyecto en Delphi 2010 entonces si es problema de compatibilidad.

Cita:


Memo1
Base de datos actualizada correctamente
CARMEN B... G.... V...
CARMEN B... G.... V...
CARMEN B... G.... V...
La próxima semana espero publicar una alternativa para conectarse a webservice sin utilizar el WSDL importer. Ya te dejo saber cuando lo tenga listo.

Saludos

apicito 28-08-2011 00:01:13

No soy capaz de entender como es posible que mi proyecto a mi no me funcione y a ti si, utilizando ambos Delphi XE. Tendrás en tu delphi algun componente que falta en mi instalación?

apicito 02-09-2011 19:37:28

[SOLUCIONADO] Como leer un TRemotable que proviene de un webservice Responder a Tema
 
Después de horas y horas intentando hacer cosas distintas, pero casi siempre haciendo lo mismo, he conseguido solucionar el problema de la lectura de TRemotable.
[SOLUCION] Descargarme la última versión de Delphi XE2 trial y funcionó a la primera. Osea que es un defecto de las versiones anteriores de delphi.
Gracias por la colaboración. Especialmente a Egostar por el tiempo que le dedicó a mi problema.

Codigo:
Unit generada por wsImporter:
Código Delphi [-]
  registroBean         = class;                 { "http://xxxxxxx.es/"[GblCplx] }

  getListaRegistrosResponse = array of registroBean;   { "http://xxxx.es/"[Lit][GblCplx] }

  registroBean = class(TRemotable)
  private
    Fasunto: string;
    Fasunto_Specified: boolean;
    FcorreoElectronico: string;
    FcorreoElectronico_Specified: boolean;
    .......

  ConsolidacionWS = interface(IInvokable)
  ['{8796BA36-EF66-FC3D-8199-9C6A7C27E916}']
    function  getEstado(const entidad: string): string; stdcall;
    function  getListaRegistros(const entidad: string): getListaRegistrosResponse; stdcall;
    function  resetFechaRegistrosEntrada: string; stdcall;
  end;

function GetConsolidacionWS(UseWSDL: Boolean=System.False; Addr: string=''; HTTPRIO: THTTPRIO = nil): ConsolidacionWS;
La unit que usa lo anterior:
Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
var i : Integer;
    Consultas: ConsolidacionWS;
    Lista: getListaRegistrosResponse;
    Entidad: string;
begin
  Entidad := '004';
  Consultas := GetConsolidacionWS(true,'',nil);
  memo1.Lines.Add('======================================');
  Lista := Consultas.getListaRegistros(Entidad);
  for i := 0 to High(Lista) do begin
    //:::::::
    memo1.Lines.Add(lista[i].nombre);
    //:::::::
  end;
  memo1.Lines.Add('---------------------------------------');
end;

egostar 02-09-2011 20:25:47

Hola

Cita:

Empezado por apicito (Mensaje 410284)
No soy capaz de entender como es posible que mi proyecto a mi no me funcione y a ti si, utilizando ambos Delphi XE. Tendrás en tu delphi algun componente que falta en mi instalación?

Caray, no había visto este mensaje

Me alegra que al final hayas resuelto el problema, en realidad no entiendo porque no te funcionó con XE, no tengo ningún componente adicional (aún me niego a utilizar componentes extras), incluso, la versión que tengo es la profesional, es decir, lo más básico.

En fin, lo dicho, me alegra que ya esté funcionando y no hay nada que agradecer, también a mi me sirvió para aprender a crear y manipular arreglos TRemotable, son interesantes :)

Saludos

apicito 02-09-2011 22:48:41

Seguramente mi versión era distinta a la tuya.
Repito, gracias.


La franja horaria es GMT +2. Ahora son las 19:44:19.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi