json - Disappearing SubDetail TObjectList when JSonToObject -
this first question. sorry english.
i have classes this:
tsfis_s = class(tpersistent) private _sfis_mid : integer; public property sfis_mid : integer read _sfis_mid write _sfis_mid; end; tsfis_d = class(tpersistent) private _sfis_mid : integer; _sfis_s : tobjectlist<tsfis_s>; public property sfis_mid : integer read _sfis_mid write _sfis_mid; property sfis_s : tobjectlist<tsfis_s> read _sfis_s write _sfis_s; end; tsfis_m = class(tpersistent) private _sfis_mid : integer; _sfis_d : tobjectlist<tsfis_d>; public property sfis_mid : integer read _sfis_mid write _sfis_mid; property sfis_d : tobjectlist<tsfis_d> read _sfis_d write _sfis_d; function tojson:tjsonvalue; destructor destroy; end;
i trying convert tsfis_m object json , revert object datasnap application. use converts , reverters datatypes (tobjectlist , tobjectlist)
{ tsfis_m } function jsontosfis_m(json: tjsonvalue): tsfis_m; var unmarshaller: tjsonunmarshal; begin if json tjsonnull exit(nil); unmarshaller := tjsonunmarshal.create; try unmarshaller.registerreverter(tsfis_m, '_fistar', procedure(data: tobject; field: string; arg: string) var ctx: trtticontext; datetime : tdatetime; begin datetime := encodedatetime(strtoint(copy(arg, 7, 4)), strtoint(copy(arg, 4, 2)), strtoint(copy(arg, 1, 2)), strtoint (copy(arg, 12, 2)), strtoint(copy(arg, 15, 2)), strtoint(copy(arg, 18, 2)), 0); ctx.gettype(data.classtype).getfield(field).setvalue(data, datetime); end ); unmarshaller.registerreverter(tsfis_d, '_sfis_s', procedure(data: tobject; field: string; args: tlistofobjects) var obj: tobject; sfiss: tobjectlist<tsfis_s>; sfis, sfisnew: tsfis_s; begin if tsfis_d(data)._sfis_s=nil tsfis_d(data)._sfis_s := tobjectlist<tsfis_s>.create(true); sfiss := tsfis_d(data)._sfis_s; sfiss.clear; obj in args begin sfis := obj tsfis_s; sfisnew := tsfis_s.create; sfiss.add(sfisnew); sfisnew._sfis_mid := sfis._sfis_mid; end; end ); unmarshaller.registerreverter(tsfis_m, '_sfis_d', procedure(data: tobject; field: string; args: tlistofobjects) var obj: tobject; sfisd: tobjectlist<tsfis_d>; sfis, sfisnew: tsfis_d; i: integer; begin if tsfis_m(data)._sfis_d=nil tsfis_m(data)._sfis_d := tobjectlist<tsfis_d>.create(true); sfisd := tsfis_m(data)._sfis_d; sfisd.clear; obj in args begin sfis := obj tsfis_d; sfisnew := tsfis_d.create; sfisd.add(sfisnew); sfisnew._sfis_mid := sfis._sfis_mid; end; end ); exit(unmarshaller.unmarshal(json) tsfis_m) unmarshaller.free; end; end; function tsfis_m.tojson: tjsonvalue; var marshaller: tjsonmarshal; begin if assigned(self) begin marshaller := tjsonmarshal.create(tjsonconverter.create); try marshaller.registerconverter(tsfis_m, '_sfis_d', function(data: tobject; field: string): tlistofobjects var fisd: tobjectlist<tsfis_d>; i: integer; begin fisd := tsfis_m(data)._sfis_d; setlength(result, fisd.count); if fisd.count > 0 := 0 fisd.count - 1 result[i] := fisd[i]; end); marshaller.registerconverter(tsfis_m, '_fistar', function(data: tobject; field: string): string var ctx: trtticontext; date : tdatetime; begin date := ctx.gettype(data.classtype).getfield(field).getvalue(data).astype<tdatetime>; result := formatdatetime('dd.mm.yyyy hh:nn:ss', date); end); marshaller.registerconverter(tsfis_d, '_sfis_s', function(data: tobject; field: string): tlistofobjects var fisd: tobjectlist<tsfis_s>; i: integer; begin fisd := tsfis_d(data)._sfis_s; setlength(result, fisd.count); if fisd.count > 0 := 0 fisd.count - 1 result[i] := fisd[i]; end); exit(marshaller.marshal(self)) marshaller.free; end; end else exit(tjsonnull.create); end;
and example put 1 button , 2 memo on form. , try created object convert json, json.tostring memo1. , convert jsonvalue object.
procedure tform1.button1click(sender: tobject); var mainfis : tsfis_m; mainfis2 : tsfis_m; dfis : tsfis_d; sfis : tsfis_s; begin mainfis := tsfis_m.create; mainfis.sfis_d := tobjectlist<tsfis_d>.create(true); dfis := tsfis_d.create; dfis._sfis_mid := 1; mainfis.sfis_d.add(dfis); sfis := tsfis_s.create; sfis._sfis_mid := 1; dfis.sfis_s := tobjectlist<tsfis_s>.create(true); dfis.sfis_s.add(sfis); memo1.text := mainfis.tojson.tostring; edit1.text := inttostr(mainfis.sfis_d[0].sfis_s.count); mainfis2 := jsontosfis_m(mainfis.tojson); edit2.text := inttostr(mainfis2.sfis_d[0].sfis_s.count); // access violation. because mainfis2.sfis_d[0].sfis_s = nil (that's problem. why?) memo2.text := mainfis2.tojson.tostring; end;
but when this. tsfis_s disappearing. in first step (objecttojson) no problem.
{"type":"unit1.tsfis_m","id":1,"fields": {"_sfis_mid":0,"_sfis_d": [ {"type":"unit1.tsfis_d","id":2,"fields": {"_sfis_mid":1,"_sfis_s": [ {"type":"unit1.tsfis_s","id":3,"fields":{"_sfis_mid":1} } ] } } ] } }
but when trying revert object reverter goes wrong.
i can't found problem. what's fault.
thanks
ps: if didn't explain, sample code here: http://goo.gl/3qnsw
Comments
Post a Comment