|
Antwort |
Registriert seit: 25. Jan 2006 8 Beiträge |
#1
Hallo,
ich versuche seit mehreren Tagen ein Array an einen in Delphi 2010prof erstellten Webservice zu übergeben. Aber iergendwie habe ich da einen Denkfehler drin. Es geht darum ein Array von Messwerten zu übergeben ca 30000. Hier mal was ich bis jetzt habe: Auf der ServerSeite....
Delphi-Quellcode:
Funktionen und Klassen für die Authentifizierung habe ich weggelassen der Länge wegen.
unit T_WEBSERVICEIntf;
interface uses InvokeRegistry, Types, XSBuiltIns,Classes; type //Responseklasse für TResponse_Write_Messwert TResponse_Write_Messwert = class(TRemotable) private FStatus:AnsiString; FErrorText:AnsiString; published property Status:AnsiString read FStatus write FStatus; property ErrorText:AnsiString read FErrorText write FErrorText; end; //Requestklasse für TRequest_WriteMesswert TRequest_WriteMesswert = class(TRemotable) private FStatus:AnsiString; FTabelle:AnsiString; FTRIC:AnsiString; FAuftrag:AnsiString; FBezeichnung:AnsiString; FWertArt:AnsiString; FWertStr:AnsiString; FOkStat:AnsiString; FNr:Integer; FWertInt:Integer; FSatzNr:Integer; FWertDouble:double; FErrorText:AnsiString; published property Status:AnsiString read FStatus write FStatus; property Tabelle:AnsiString read FTabelle write FTabelle; property TRIC:AnsiString read FTRIC write FTRIC; property Auftrag:AnsiString read FAuftrag write FAuftrag; property Bezeichnung:AnsiString read FBezeichnung write FBezeichnung; property WertArt:AnsiString read FWertArt write FWertArt; property WertStr:AnsiString read FWertStr write FWertStr; property OkStat:AnsiString read FOkStat write FOkStat; property Nr:Integer read FNr write FNr; property WertInt:Integer read FWertInt write FWertInt; property SatzNr:Integer read FSatzNr write FSatzNr; property WertDouble:double read FWertDouble write FWertDouble; property ErrorText:AnsiString read FErrorText write FErrorText; end; //Array für Messwerte TRequest_WriteMesswertArray1 = Array of TRequest_WriteMesswert; //Requestklasse für TRequest_WriteMesswertArray TRequest_WriteMesswertArray = class(TRemotable) private FMesswertAnzahl:Cardinal; FMesswerte:TRequest_WriteMesswertArray1; published property MesswertAnzahl:Cardinal read FMesswertAnzahl write FMesswertAnzahl; property Messwerte:TRequest_WriteMesswertArray1 read FMesswerte write FMesswerte; end; //Responseklasse für TResponse_GetMerkmale TResponse_WriteMesswertArray = class(TRemotable) private FStatus:AnsiString; FErrorText:AnsiString; published property Status:AnsiString read FStatus write FStatus; property ErrorText:AnsiString read FErrorText write FErrorText; end; { Aufrufbare Interfaces müssen von IInvokable abgeleitet sein } ITESIS_WEBSERVICE = interface(IInvokable) ['{CB15C88B-A6B2-460E-B0AA-AEAEABFEF217}'] function WriteMesswert(const Authent:TAuth; MesswertData:TRequest_WriteMesswert):TResponse_Write_Messwert; stdcall; function WriteMesswertArray(const Authent:TAuth; MesswertArray:TRequest_WriteMesswertArray):TResponse_WriteMesswertArray; stdcall; end; implementation initialization { Aufrufbares Interface muss registriert werden } InvRegistry.RegisterInterface(TypeInfo(IT_WEBSERVICE)); end. Jetzt die Implementierung auf dem Server:
Delphi-Quellcode:
Jetzt die auf dem Client importierte Klassen:
unit TESIS_WEBSERVICEImpl;
interface uses InvokeRegistry, Types, XSBuiltIns, TESIS_WEBSERVICEIntf,WebDataModul,SysUtils, Classes; type { TT_WEBSERVICE } TT_WEBSERVICE = class(TInvokableClass, IT_WEBSERVICE) public function WriteMesswert(const Authent:TAuth; MesswertData:TRequest_WriteMesswert):TResponse_Write_Messwert; stdcall; function WriteMesswertArray(const Authent:TAuth; MesswertArray:TRequest_WriteMesswertArray):TResponse_WriteMesswertArray; stdcall; end; implementation #function TT_WEBSERVICE.WriteMesswert(const Authent:TAuth; MesswertData:TRequest_WriteMesswert):TResponse_Write_Messwert; var s:string; UserID,ErrorText,h:String; b:boolean; err:Integer; begin if WB=nil then WB:=TWebDatamod.Create(nil); if Result=nil then Result:=TResponse_Write_Messwert.Create; if WB.TestAuthentifizierung(Authent.UserName,Authent.UserPasswordHash,'WriteMesswert',Authent.DB,s)=0 then begin err:=WB.FIsTRICValid(MesswertData.TRIC,b,ErrorText); if err <> 0 then begin Result.Status:=IntToStr(err); Result.ErrorText:=ErrorText; Exit; end; if not WB.StringOk(MesswertData.Bezeichnung,WebDataModul.ALPHA) then begin Result.Status:='-1'; Result.ErrorText:=ErrorText; Exit; end; err:=WB.FIsAuftragValid(MesswertData.Auftrag,b,ErrorText); if err <> 0 then begin Result.Status:=IntToStr(err); Result.ErrorText:=ErrorText; Exit; end; b:=WB.StringOk(MesswertData.Tabelle,WebDataModul.DBALPHA); if b=false then begin Result.Status:=IntToStr(err); Result.ErrorText:='Der Tabellenname enthält unzulässige Zeichen. Zulässig sind a-z,A-Z,_,-,0-9'; Exit; end; err:=WB.FWriteMesswert(MesswertData,ErrorText); if err=0 then begin Result.Status:=IntToStr(OK); Result.ErrorText:=''; end else begin Result.Status:=IntToStr(err); Result.ErrorText:=ErrorText; end; end else begin Result.Status:='-1'; Result.ErrorText:=s; end; end; function TT_WEBSERVICE.WriteMesswertArray(const Authent:TAuth; MesswertArray:TRequest_WriteMesswertArray):TResponse_WriteMesswertArray; var s:string; UserID,ErrorText,h:String; b:boolean; err:Integer; i:Cardinal; begin if WB=nil then WB:=TWebDatamod.Create(nil); if Result=nil then Result:=TResponse_WriteMesswertArray.Create; if WB.TestAuthentifizierung(Authent.UserName,Authent.UserPasswordHash,'WriteMesswertArray',Authent.DB,s)=0 then begin for I := 0 to MesswertArray.MesswertAnzahl - 1 do begin err:=WB.FWriteMesswert(MesswertArray.Messwerte[i],ErrorText); if err<>0 then begin //Abbruch im Fehlerfall Result.Status:=IntToStr(err); Result.ErrorText:=ErrorText+' Nicht alle Daten geschrieben. Letzter Datensatz-Nr im Array: '+IntToStr(i); Exit; end; end; if err=0 then begin Result.Status:=IntToStr(OK); Result.ErrorText:=''; end; end; end; initialization { Aufrufbare Klassen müssen registriert werden } InvRegistry.RegisterInvokableClass(TT_WEBSERVICE); end.
Delphi-Quellcode:
Jetzt die Aufrufe der Funktionen:
unit ITESIS_WEBSERVICE1;
interface uses InvokeRegistry, SOAPHTTPClient, Types, XSBuiltIns; type // ************************************************************************ // // Die folgenden Typen, auf die im WSDL-Dokument Bezug genommen wird, sind in dieser Datei // nicht repräsentiert. Sie sind entweder Aliase[@] anderer repräsentierter Typen oder auf sie wurde Bezug genommen, // aber sie sind in diesem Dokument nicht[!] deklariert. Die Typen aus letzterer Kategorie // sind in der Regel vordefinierten/bekannten XML- oder Embarcadero-Typen zugeordnet; sie könnten aber auf // ein inkorrektes WSDL-Dokument hinweisen, das einen Schematyp nicht deklariert oder importiert hat. // ************************************************************************ // // !:string - "http://www.w3.org/2001/XMLSchema"[Gbl] // !:boolean - "http://www.w3.org/2001/XMLSchema"[Gbl] // !:int - "http://www.w3.org/2001/XMLSchema"[Gbl] // !:double - "http://www.w3.org/2001/XMLSchema"[Gbl] // !:unsignedInt - "http://www.w3.org/2001/XMLSchema"[Gbl] TRequest_WriteMesswert = class; { "urn:T_WEBSERVICEIntf"[GblCplx] } TResponse_Write_Messwert = class; { "urn:T_WEBSERVICEIntf"[GblCplx] } TRequest_WriteMesswertArray = class; { "urn:T_WEBSERVICEIntf"[GblCplx] } TResponse_WriteMesswertArray = class; { "urn:T_WEBSERVICEIntf"[GblCplx] } // ************************************************************************ // // XML : TRequest_WriteMesswert, global, <complexType> // Namespace : urn:TESIS_WEBSERVICEIntf // ************************************************************************ // TRequest_WriteMesswert = class(TRemotable) private FStatus: string; FTabelle: string; FTRIC: string; FAuftrag: string; FBezeichnung: string; FWertArt: string; FWertStr: string; FOkStat: string; FNr: Integer; FWertInt: Integer; FSatzNr: Integer; FWertDouble: Double; FErrorText: string; published property Status: string read FStatus write FStatus; property Tabelle: string read FTabelle write FTabelle; property TRIC: string read FTRIC write FTRIC; property Auftrag: string read FAuftrag write FAuftrag; property Bezeichnung: string read FBezeichnung write FBezeichnung; property WertArt: string read FWertArt write FWertArt; property WertStr: string read FWertStr write FWertStr; property OkStat: string read FOkStat write FOkStat; property Nr: Integer read FNr write FNr; property WertInt: Integer read FWertInt write FWertInt; property SatzNr: Integer read FSatzNr write FSatzNr; property WertDouble: Double read FWertDouble write FWertDouble; property ErrorText: string read FErrorText write FErrorText; end; // ************************************************************************ // // XML : TResponse_Write_Messwert, global, <complexType> // Namespace : urn:T_WEBSERVICEIntf // ************************************************************************ // TResponse_Write_Messwert = class(TRemotable) private FStatus: string; FErrorText: string; published property Status: string read FStatus write FStatus; property ErrorText: string read FErrorText write FErrorText; end; TRequest_WriteMesswertArray1 = array of TRequest_WriteMesswert; { "urn:T_WEBSERVICEIntf"[GblCplx] } // ************************************************************************ // // XML : TRequest_WriteMesswertArray, global, <complexType> // Namespace : urn:T_WEBSERVICEIntf // ************************************************************************ // TRequest_WriteMesswertArray = class(TRemotable) private FMesswertAnzahl: Cardinal; FMesswerte: TRequest_WriteMesswertArray1; public destructor Destroy; override; published property MesswertAnzahl: Cardinal read FMesswertAnzahl write FMesswertAnzahl; property Messwerte: TRequest_WriteMesswertArray1 read FMesswerte write FMesswerte; end; // ************************************************************************ // // XML : TResponse_WriteMesswertArray, global, <complexType> // Namespace : urn:T_WEBSERVICEIntf // ************************************************************************ // TResponse_WriteMesswertArray = class(TRemotable) private FStatus: string; FErrorText: string; published property Status: string read FStatus write FStatus; property ErrorText: string read FErrorText write FErrorText; end; // ************************************************************************ // // Namespace : urn:T_WEBSERVICEIntf-IT_WEBSERVICE // soapAction: urn:T_WEBSERVICEIntf-IT_WEBSERVICE#%operationName% // Transport : http://schemas.xmlsoap.org/soap/http // Stil : rpc // Bindung : IT_WEBSERVICEbinding // Service : IT_WEBSERVICEservice // Port : IT_WEBSERVICEPort // URL : http://x.x.x.x/scripts/T_WEBSERV.dll/soap/IT_WEBSERVICE // ************************************************************************ // IT_WEBSERVICE = interface(IInvokable) ['{1A035FD6-E9F4-4ABB-0DC9-73DC5AAD81FD}'] function WriteMesswert(const Authent: TAuth; const MesswertData: TRequest_WriteMesswert): TResponse_Write_Messwert; stdcall; function WriteSerienNr(const Authent: TAuth; const WriteSn: TRequest_WriteSerienNr): TResponse_WriteSerienNr; stdcall; function WriteMesswertArray(const Authent: TAuth; const MesswertArray: TRequest_WriteMesswertArray): TResponse_WriteMesswertArray; stdcall; end; function GetIT_WEBSERVICE(UseWSDL: Boolean=System.False; Addr: string=''; HTTPRIO: THTTPRIO = nil): IT_WEBSERVICE; implementation uses SysUtils; function GetIT_WEBSERVICE(UseWSDL: Boolean; Addr: string; HTTPRIO: THTTPRIO): IT_WEBSERVICE; const defWSDL = 'http://x.x.x.x/scripts/T_WEBSERV.dll/wsdl/IT_WEBSERVICE'; defURL = 'http://x.x.x.x/scripts/T_WEBSERV.dll/soap/IT_WEBSERVICE'; defSvc = 'IT_WEBSERVICEservice'; defPrt = 'IT_WEBSERVICEPort'; 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 IT_WEBSERVICE); 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; destructor TRequest_WriteMesswertArray.Destroy; var I: Integer; begin for I := 0 to System.Length(FMesswerte)-1 do SysUtils.FreeAndNil(FMesswerte[I]); System.SetLength(FMesswerte, 0); inherited Destroy; end; initialization InvRegistry.RegisterInterface(TypeInfo(IT_WEBSERVICE), 'urn:T_WEBSERVICEIntf-IT_WEBSERVICE', ''); InvRegistry.RegisterDefaultSOAPAction(TypeInfo(IT_WEBSERVICE), 'urn:T_WEBSERVICEIntf-IT_WEBSERVICE#%operationName%'); RemClassRegistry.RegisterXSClass(TRequest_WriteMesswert, 'urn:T_WEBSERVICEIntf', 'TRequest_WriteMesswert'); RemClassRegistry.RegisterXSClass(TResponse_Write_Messwert, 'urn:T_WEBSERVICEIntf', 'TResponse_Write_Messwert'); RemClassRegistry.RegisterXSInfo(TypeInfo(TRequest_WriteMesswertArray1), 'urn:T_WEBSERVICEIntf', 'TRequest_WriteMesswertArray1'); RemClassRegistry.RegisterXSClass(TRequest_WriteMesswertArray, 'urn:T_WEBSERVICEIntf', 'TRequest_WriteMesswertArray'); RemClassRegistry.RegisterXSClass(TResponse_WriteMesswertArray, 'urn:T_WEBSERVICEIntf', 'TResponse_WriteMesswertArray'); end.
Delphi-Quellcode:
Jetzt der Versuch mit Array:
procedure TForm1.AdvGlowButton11Click(Sender: TObject);
var //Diese Funktion klappt. Die Werte werden vom Webservice angenommen und in die DB eingetragen. myService:IT_WEBSERVICE; response:TResponse_Write_Messwert; request:TRequest_WriteMesswert; auth:TAuth; begin request:=TRequest_WriteMesswert.Create; response:=TResponse_Write_Messwert.Create; auth:=TAuth.Create; auth.UserName:=AdvEdit2.Text; auth.UserPasswordHash:=HashMD5(AdvEdit3.Text); if RadioGroup1.ItemIndex=0 then auth.DB:='Testsystem' else auth.DB:='Produktiv'; myService:=HTTPRio1 as IT_WEBSERVICE; request.Status:=AdvEdit37.Text; request.Tabelle:=Advedit34.Text; request.TRIC:=AdvEdit32.Text; request.Auftrag:=Advedit30.Text; request.Bezeichnung:=AdvEdit36.Text; request.WertArt:=Advedit39.Text; request.WertStr:=AdvEdit41.Text; request.OkStat:=Advedit40.Text; request.Nr:=StrToInt(AdvEdit44.Text); request.WertInt:=StrToInt(AdvEdit42.Text); request.SatzNr:=StrToInt(Advedit38.Text); request.WertDouble:=StrToFloat(Advedit43.Text); response:=myService.WriteMesswert(auth,request); AdvOfficeStatusbar1.Panels[1].Text:=response.ErrorText; AdvOfficeStatusBar1.Panels[0].Text:=response.Status; if RadioGroup1.ItemIndex=0 then AdvOfficeStatusBar1.Panels[2].Text:='Testsystem' else AdvOfficeStatusBar1.Panels[2].Text:='Produktiv'; response.Free; request.Free; auth.Free; end;
Delphi-Quellcode:
Ist das Ganze mit einem Array überhaupt möglich??
procedure TForm1.AdvGlowButton14Click(Sender: TObject);
var myService:IT_WEBSERVICE; response:TResponse_WriteMesswertArray; request:TRequest_WriteMesswertArray; arrayMesswerte:array of TRequest_WriteMesswert; auth:TAuth; i,k:integer; a:Cardinal; begin request:=TRequest_WriteMesswertArray.Create; response:=TResponse_WriteMesswertArray.Create; //arrayMesswerte:=TRequest_WriteMesswertArray.Create(); auth:=TAuth.Create; auth.UserName:=AdvEdit2.Text; auth.UserPasswordHash:=HashMD5(AdvEdit3.Text); if RadioGroup1.ItemIndex=0 then auth.DB:='Testsystem' else auth.DB:='Produktiv'; myService:=HTTPRio1 as IT_WEBSERVICE; k:=0; request.MesswertAnzahl:=StrToInt(AdvEdit60.Text); a:=request.MesswertAnzahl; SetLength(arrayMesswerte,a); for i := 0 to StrToInt(AdvEdit60.Text)-1 do begin ArrayMesswerte[i].Status:=AdvEdit52.Text; <- Hier tritt eine exception auf ArrayMesswerte[i].Tabelle:=Advedit50.Text; ArrayMesswerte[i].TRIC:=AdvEdit49.Text; ArrayMesswerte[i].Auftrag:=Advedit48.Text; ArrayMesswerte[i].Bezeichnung:=AdvEdit51.Text; ArrayMesswerte[i].WertArt:=Advedit54.Text; ArrayMesswerte[i].WertStr:=AdvEdit56.Text; ArrayMesswerte[i].OkStat:=Advedit55.Text; ArrayMesswerte[i].Nr:=k+1; ArrayMesswerte[i].WertInt:=StrToInt(AdvEdit57.Text); ArrayMesswerte[i].SatzNr:=StrToInt(Advedit53.Text); ArrayMesswerte[i].WertDouble:=StrToFloat(Advedit58.Text); end; request.Messwerte:=arrayMesswerte; response:=myService.WriteMesswertArray(auth,request); AdvOfficeStatusbar1.Panels[1].Text:=response.ErrorText; AdvOfficeStatusBar1.Panels[0].Text:=response.Status; if RadioGroup1.ItemIndex=0 then AdvOfficeStatusBar1.Panels[2].Text:='Testsystem' else AdvOfficeStatusBar1.Panels[2].Text:='Produktiv'; response.Free; request.Free; auth.Free; end; Was mach ich falsch? Client: Delphi XE Studio prof Server: Delphi 2010 Studio prof Gruß Mike |
Zitat |
Registriert seit: 6. Mär 2003 Ort: Meißen 876 Beiträge Delphi 10.1 Berlin Professional |
#2
Hallo,
der Fehler liegt meiner Meinung nach hier:
Delphi-Quellcode:
du hast ja trotzdem ein array of "Object" und kein array of "Record" und mußt deine Array-Elemente auch erzeugen.
SetLength(arrayMesswerte,a);
for i := 0 to StrToInt(AdvEdit60.Text)-1 do begin ArrayMesswerte[i]:=TRequest_WriteMesswert.create; // <--- das fehlt ArrayMesswerte[i].Status:=AdvEdit52.Text; <- Hier tritt eine exception auf ArrayMesswerte[i].Tabelle:=Advedit50.Text; .... Gruß Frank Lükes Grundlage der Programmierung: Es wird nicht funktionieren (Murphy) |
Zitat |
Ansicht |
Linear-Darstellung |
Zur Hybrid-Darstellung wechseln |
Zur Baum-Darstellung wechseln |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
LinkBack URL |
About LinkBacks |