#1 2014-04-25 01:53:58

avista
Member
Registered: 2014-01-06
Posts: 63

'Invalid fake' error message

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

#2 2014-04-25 08:17:22

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,272
Website

Re: 'Invalid fake' error message

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

Board footer

Powered by FluxBB