#1 2014-01-16 15:47:10

dorival
Member
From: Brasil
Registered: 2013-04-17
Posts: 35

using different version of a "DTO" class

Hello ab,

I have this interface to comunication between client and server.

  IClient = interface(IInvokable)
    ['{3E095FAD-5D65-4A27-82D5-6492F197F402}']
    procedure SomeMethod (AClientDTO: TClientDTO);
  end;

In the server, I have this version of TClientDTO:

TClientDTO = class(TSQLRecord)
  private
    FCode: integer;
    FName: RawUTF8;
  published
    property Code: Integer read FCode write FCode;
    property Name: RawUTF8 read FName write FName;
  end;

and the client has this version of TClientDTO (a new property):

TClientDTO = class(TSQLRecord)
  private
    FCode: integer;
    FName: RawUTF8;
    FCelfone: RawUTF8;
  published
    property Code: Integer read FCode write FCode;
    property Name: RawUTF8 read FName write FName;
    property Celfone: RawUTF8 read FCelfone write FCelfone;
  end;

when I execute the method SomeMethod in the client side, I receive the error 400 – bad request.

May be you ask me if this situation is common to me. Yes, the client can be the last version and the server can be a old version...

Well, my question is: Can I force the server ignore the property Celfone?

Offline

#2 2014-01-16 19:35:28

dorival
Member
From: Brasil
Registered: 2013-04-17
Posts: 35

Re: using different version of a "DTO" class

I found this... if I change the lines bellow, my problem is resolved.

function JSONToObject(var ObjectInstance; From: PUTF8Char; var Valid: boolean;
  TObjectListItemClass: TClass=nil): PUTF8Char;
...
    P := ClassFieldPropWithParentsFromUTF8(PPointer(Value)^,PropName);
    if P=nil then
    begin
      Valid := true; // return it until is true...
      PropValue := GetJSONField(From,From,@wasString,@EndOfObject); // get value and ignore de value
      continue; //exit; // unknwown property
    end;
...

What can I do ?

Offline

#3 2014-01-20 18:53:51

edismo
Member
From: Brazil
Registered: 2013-10-04
Posts: 34

Re: using different version of a "DTO" class

You can help Arnaud?

Offline

#4 2014-01-22 09:28:50

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

Re: using different version of a "DTO" class

I've added a new TJSONToObjectOptions optional parameter in JSONToObject() / ObjectToJSON() functions and associated WriteObject() method.

It should add the behavior you were missing.

See http://synopse.info/fossil/info/c826016e40

Offline

#5 2014-01-22 10:01:04

edismo
Member
From: Brazil
Registered: 2013-10-04
Posts: 34

Re: using different version of a "DTO" class

Thanks AB.
Let's test it.

Offline

#6 2014-01-22 10:10:27

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

Re: using different version of a "DTO" class

Ensure you retrieve the latest revision - c826016e40 may be broken, but http://synopse.info/fossil/info/6fc099a149 should be fine (and including all new variant-based features).

BTW, the new variant types with late-binding are a very good candidate for dynamic DTO classes: no type definition to write, just use properties as you need them.
smile

Offline

#7 2014-02-11 12:56:32

dorival
Member
From: Brasil
Registered: 2013-04-17
Posts: 35

Re: using different version of a "DTO" class

Hello AB,
Thank you. Sorry for not replying earlier ... I was on vacation :-).

Offline

#8 2014-02-11 16:10:07

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

Re: using different version of a "DTO" class

Hope you did enjoy your vacation!
big_smile

Offline

#9 2014-05-15 18:10:14

dorival
Member
From: Brasil
Registered: 2013-04-17
Posts: 35

Re: using different version of a "DTO" class

Hello AB,

on this subject, I have a question:
on an http client, how should I set the new attribute of my DTO class?

I saw that in the method ...

function TServiceMethod.InternalExecute(... 

... call the function without any parameters:

Par: JSONToObject = (Objects [IndexVar] Pair valid); 

So I changed as below so that the server does not generate an error as DTO customer has with a new attribute.

Par: JSONToObject = (Objects [IndexVar] Pair valid, nil, [j2oIgnoreUnknownProperty]); 

Offline

#10 2014-06-10 12:28:39

dorival
Member
From: Brasil
Registered: 2013-04-17
Posts: 35

Re: using different version of a "DTO" class

Hello,

Using a custom reader method bellow:

class function TServerClass.MyClassCustomReader(const aValue: TObject; aFrom: PUTF8Char; var aValid: Boolean; aOptions: TJSONToObjectOptions): PUTF8Char;
var 
  oDTOMyClass: TDTOMyClass;
begin
  aOptions := aOptions + [j2oIgnoreUnknownProperty];
  result := aFrom;
  oDTOMyClass := TDTOMyClass(aValue);
  JSONToObject(oDTOMyClass, aFrom, aValid, nil, aOptions);
  oDTOMyClass := nil;
end;

...and registering the method with the code bellow:

TJSONSerializer.RegisterCustomSerializer(TDTOMyClass, MyClassCustomReader, nil);

...my code enter in a loop (of course).
JSONToObject->MyClassCustomReader->JSONToObject->MyClassCustomReader....

I need just include the j2oIgnoreUnknownProperty option. What the best way to do it without recreate another JSONToObject ?

Thanks.
Dorival

Offline

#11 2014-06-10 20:52:36

dorival
Member
From: Brasil
Registered: 2013-04-17
Posts: 35

Re: using different version of a "DTO" class

well I changed de method (mormot.pas)

function JSONToObject(var ObjectInstance; From: PUTF8Char; var Valid: boolean; TObjectListItemClass: TClass=nil; 
Options: TJSONToObjectOptions=[]): PUTF8Char;

...to...

function JSONToObject(var ObjectInstance; From: PUTF8Char; var Valid: boolean; TObjectListItemClass: TClass=nil; Options: 
TJSONToObjectOptions=[j2oIgnoreUnknownProperty]): PUTF8Char;

(Options default j2oIgnoreUnknownProperty ).

It´s work for me. Someone knows if can it do some problem?

Dorival

Last edited by dorival (2014-06-10 20:53:16)

Offline

Board footer

Powered by FluxBB