0

How to get JSON, which contains only Name and Flags?

  TUser = class
  private
    FName:  string;
    FFlags: UInt32;
    FFields: UInt32;
    FCreated: TDateTime;
  public
    property Name: string read FName write FName;
    property Flags: UInt32 read FFlags write FFlags;
    property Fields: UInt32 read FFields write FFields;
    property Created: TDateTime read FCreated write FCreated;
    constructor Create;
  end;

Usually is used all fields of this class:

var
  User: TUser
  sJson: string;

sJson := User.AsJson;

but sometimes I needed a JSON with Name and Flags fields only. Currently, to get such JSON I use such code:

var
  User: TUser
  usr: ISuperObject;
  sJson: string;

usr := SO(User.AsJson);
usr.Remove('Fields');
usr.Remove('Created');
sJson := usr.AsJSON;

But I think is not optimal code (actually in real code I have 15 fields and need to remove 12). How to do that faster?

Updated (another method):

May be this will be more faster and useful for my purpose?

usr := SO('');
usr.S['Name']  := User.Name;
usr.I['Flags'] := User.Flags;
sJson := usr.AsJSON;
Alex Egorov
  • 907
  • 7
  • 26
  • What exactly is the question? You already appear to have two ways of doing what you want. – David Heffernan Feb 07 '22 at 21:57
  • @DavidHeffernan, I think you are right, updated part of my question is completely contains what I need, but I need something "universal": sJson := User.AsJSON('Name', 'Flags'); - provide filled list, which I want to see in my JSON – Alex Egorov Feb 08 '22 at 04:15
  • you can use https://github.com/paolo-rossi/delphi-neon, it will help you ignore fields using [neonIgnore] attribute. also in this case I would suggest using records so you benefit from the auto memory management. – Nasreddine Galfout Feb 08 '22 at 10:52
  • @NasreddineGalfout, xsuperobject support [DISABLE] attribute, but I need to remove some fields by request, usually, I need all fields in the JSON. Currently I have idea to create some TUserSmall class with the necessary fields and when needed assign them from TUser class and generate the JSON. Need tests to check what will be faster. About record usage - some years ago I'm having problems with the nextgen compiler with serializing records. Now it is fixed? – Alex Egorov Feb 08 '22 at 11:11
  • 1
    @AlexEgorov look up NeonIncludeAttribute it has many options – Nasreddine Galfout Feb 09 '22 at 10:05
  • and yes I think, from my experience I have no problems with using records classic or managed on 10.4 and d11. – Nasreddine Galfout Feb 09 '22 at 10:08

1 Answers1

1

Thanks to the @NasreddineGalfout I'm found that is it possible with Neon JSON library. With INeonConfiguration I can select public or published or protected (or any combination) property fields that should be serialized. And is it what I need. Moreover deserializing with Neon is 2x much faster than with XSuperObject.

type  
  TUser = class
  private
    FName:  string;
    FFlags: UInt32;
    FFields: UInt32;
    FCreated: TDateTime;
  public
    property Name: string read FName write FName;
    property Flags: UInt32 read FFlags write FFlags;
  published
    property Fields: UInt32 read FFields write FFields;
    property Created: TDateTime read FCreated write FCreated;
    constructor Create;
  end;

function MyToJson(User: TUser): string;
var
  Config: INeonConfiguration;
  LJSON: TJSONValue;
  LWriter: TNeonSerializerJSON;
begin
  Config := TNeonConfiguration.Default.SetVisibility([mvPublic{, mvPublished}]);
  LWriter := TNeonSerializerJSON.Create(Config);
  try
    LJSON := LWriter.ObjectToJSON(User);
    try
      Result := TJSONUtils.ToJSON(LJSON);
    finally
      LJSON.Free;
    end;
  finally
    LWriter.Free;
  end;
end;

procedure MyFromJson(var User: TUser; const AJson: string);
var
  Config: INeonConfiguration;
  LJSON: TJSONValue;
  LReader: TNeonDeserializerJSON;
begin
  LJSON := TJSONObject.ParseJSONValue(AJson);
  if not Assigned(LJSON) then
    Exit;
  Config := TNeonConfiguration.Default.SetVisibility([mvPublic{, mvPublished}]);
  try
    LReader := TNeonDeserializerJSON.Create(Config);
    try
      LReader.JSONToObject(User, LJSON);
    finally
      LReader.Free;
    end;
  finally
    LJSON.Free;
  end;
end;
Alex Egorov
  • 907
  • 7
  • 26