You are not logged in.
Pages: 1
I've modified the calculator demo to include a method that takes an object as a parameter:
type
TIntArray = array of Integer;
TAddress = class(TPersistentWithCustomCreate)
private
FStreet: string;
FCity: string;
FZipCode: string;
FCountry: string;
FData: TIntArray;
public
constructor Create; override;
destructor Destroy; override;
published
property Street: string read FStreet write FStreet;
property City: string read FCity write FCity;
property ZipCode: string read FZipCode write FZipCode;
property Country: string read FCountry write FCountry;
property Data: TIntArray read FData write FData;
end;
TContact = class(TPersistentWithCustomCreate)
private
FId: Integer;
FFirstName: string;
FLastName: string;
FAddress: TAddress;
public
constructor Create; override;
destructor Destroy; override;
published
property Id: Integer read FId write FId;
property FirstName: string read FFirstName write FFirstName;
property LastName: string read FLastName write FLastName;
property Address: TAddress read FAddress write FAddress;
end;
ICalculator = interface(IInvokable)
['{9A60C8ED-CEB2-4E09-87D4-4A16F496E5FE}']
function Add(n1,n2: integer): integer;
function GetContact(Id: string; var Contact: TContact): Boolean;
end;
implementation
{ TAddress }
constructor TAddress.Create;
begin
inherited;
SetLength(FData, 10);
end;
destructor TAddress.Destroy;
begin
inherited;
end;
{ TContact }
constructor TContact.Create;
begin
inherited;
FAddress := TAddress.Create;
end;
destructor TContact.Destroy;
begin
FAddress.Free;
inherited;
end;
end.
In the Project 14 Client, I've added the following code:
if Client.Services['Calculator'].Get(I) then
begin
lblResult.Caption := IntToStr(I.Add(a,b));
Contact := TContact.Create;
I.GetContact('100', Contact);
end;
And in the Project 14 HTTP Server:
TServiceCalculator = class(TInterfacedObject, ICalculator)
private
public
function Add(n1,n2: integer): integer;
function GetContact(Id: string; var Contact: TContact): Boolean;
end;
function TServiceCalculator.GetContact(Id: string; var Contact: TContact): Boolean;
begin
Contact := TContact.Create;
try
Contact.FirstName := 'Joe';
Contact.LastName := 'Smith';
Contact.Address.Street := '1234 Main St.';
Result := True;
finally
end;
end;
However, the call to
I.GetContact('100', Contact);
in the Client (using HTTP / TCP-IP) results in the following error:
EInterfaceFactoryException:
Invalid fake ICalculator.GetContact interface call: : {
"ErrorCode":400,
"ErrorText":"Bad Request"
}
I must be doing something obviously wrong, but I can't see what...
BTW, I'm using the nightly build of 1 week ago.
Thanks in advance.
Last edited by avista (2014-04-25 02:42:21)
Offline
Any parameter class instance is created by the server-side caller.
You should not write Contact := TContact.Create on the server side implementation.
Try to write:
function TServiceCalculator.GetContact(Id: string; var Contact: TContact): Boolean;
begin
Contact.FirstName := 'Joe';
Contact.LastName := 'Smith';
Contact.Address.Street := '1234 Main St.';
Result := True;
end;
Why are you using a class here?
You are using the class as a DTO, in your case.
Why not use a record and text-based serialization?
It should be much easier to work with, without any need to handle memory.
Offline
Pages: 1