You are not logged in.
Hi,
I have a TSQLRecord like so :
TMzItem = class(TSQLRecordWithNames)
protected
FDescriptions : TMzNameList;
FImages : TMzImageList;
public
constructor Create; override;
destructor Destroy; override;
published
property Descriptions : TMzNameList read FDescriptions write FDescriptions;
property Images : TMzImageList read FImages write FImages;
end;
constructor TMzItem.Create;
begin
inherited;
FDescriptions := TMzNameList.Create;
FImages := TMzImageList.Create;
end;
destructor TMzItem.Destroy;
begin
FImages.Free;
FDescriptions.Free;
inherited;
end;
TMzNameList and TMzName look like :
TMzName = class(TPersistentWithCustomCreate)
private
FName: RawUTF8;
FLanguageID: TID;
public
constructor Create; overload; override;
constructor Create(const AName : RawUTF8; const ALangID : TID); overload;
function GetLanguage(const AClient : TSQLRest): TMzLanguage;
published
property LanguageID : TID read FLanguageID write FLanguageID;
property Name : RawUTF8 read FName write FName;
end;
TMzNameList = class(TObjectList)
protected
function GetItem(Index: Integer): TMzName;
procedure SetItem(Index: Integer; const Value: TMzName);
public
function Add(AObject: TMzName): Integer; inline;
property Items[Index: Integer]: TMzName read GetItem write SetItem; default;
end;
constructor TMzName.Create(const AName: RawUTF8; const ALangID: TID);
begin
Create;
FName := AName;
FLanguageID := ALangID;
end;
constructor TMzName.Create;
begin
inherited Create;
end;
function TMzName.GetLanguage(const AClient: TSQLRest): TMzLanguage;
begin
Result := TMzLanguage.Create(AClient, FLanguageID);
end;
function TMzNameList.Add(AObject: TMzName): Integer;
begin
inherited Add(TObject(AObject));
end;
function TMzNameList.GetItem(Index: Integer): TMzName;
begin
Result := TMzName(inherited Items[Index]);
end;
procedure TMzNameList.SetItem(Index: Integer; const Value: TMzName);
begin
inherited Items[Index] := TObject(Value);
end;
initialization
TJSONSerializer.RegisterClassForJSON([TMzName]);
When i create a TMzItem with some Descriptions they are saved just fine. The problem is with TMzImageList :
TMzImage = class(TPersistentWithCustomCreate)
protected
FId : integer;
FNames : TMzNameList;
FIsDefault : boolean;
FIsVisible : boolean;
public
constructor Create; overload; override;
constructor Create(const AId : integer; const AIsDefault : Boolean; const AIsVisible : Boolean); reintroduce; overload;
destructor Destroy; override;
published
property Names : TMzNameList read FNames write FNames;
property ID : integer read FId write FId;
property IsDefault : boolean read FIsDefault write FIsDefault;
property IsVisible : boolean read FIsVisible write FIsVisible;
end;
TMzImageList = class(TObjectList)
protected
function GetItem(Index: Integer): TMzImage;
procedure SetItem(Index: Integer; const Value: TMzImage);
public
function Add(AObject: TMzImage): Integer; inline;
property Items[Index: Integer]: TMzImage read GetItem write SetItem; default;
end;
function TMzImageList.Add(AObject: TMzImage): Integer;
begin
inherited Add(TObject(AObject));
end;
function TMzImageList.GetItem(Index: Integer): TMzImage;
begin
Result := TMzImage(inherited Items[Index]);
end;
procedure TMzImageList.SetItem(Index: Integer; const Value: TMzImage);
begin
inherited Items[Index] := TObject(Value);
end;
constructor TMzImage.Create(const AId: integer; const AIsDefault, AIsVisible: Boolean);
begin
Create;
FNames := TMzNameList.Create;
FId := AId;
FIsDefault := AIsDefault;
FIsVisible := AIsVisible;
end;
constructor TMzImage.Create;
begin
inherited Create;
end;
destructor TMzImage.Destroy;
begin
FNames.Free;
inherited;
end;
initialization
TJSONSerializer.RegisterClassForJSON([TMzImage]);
When i add some TMzImage to Images of TMzItem they are not saved. Instead that property is empty ('[]'). If i remove Names from TMzImage, then Images are saved properly. I have tried to debug Client.Add(item, True) and i can see that the TMzItem is properly converted to JSON along with its images and their names but not saved as such. Images is [].
Have you any suggestions?
Thank you.
trx.
Offline
How would the serialization know the type of each item of the TObjectList?
There is not such information available.
Please check the doc:
...
// - won't handle TObjectList (even if ObjectToJSON is able to serialize
// them) since has no way of knowing the object type to add (TCollection.Add
// is missing), unless: 1. you set the TObjectListItemClass property as expected,
// and provide a TObjectList object, or 2. woStoreClassName option has been
// used at ObjectToJSON() call and the corresponding classes have been previously
// registered by TJSONSerializer.RegisterClassForJSON() (or Classes.RegisterClass)
...
function JSONToObject(var ObjectInstance; From: PUTF8Char; var Valid: boolean;
TObjectListItemClass: TClass=nil; Options: TJSONToObjectOptions=[]): PUTF8Char;
See http://synopse.info/files/html/api-1.18 … ONTOOBJECT
The alternative are, as documented:
- Define TCollection/TCollectionItem types;
- Use a T*ObjArray dynamic array type, registered via TJSONSerializer.RegisterObjArrayForJSON - see http://synopse.info/files/html/api-1.18 … RAYFORJSON
In fact, T*ObjArray are just great, and automatically allocated/released if your owning class is a TPersistentAutoCreateFields or a TSynAutoCreateFields.
See http://synopse.info/files/html/api-1.18 … EATEFIELDS
Offline