Сериализация объектов в формате JSON является важной частью разработки современных приложений. В частности, в среде Delphi и Object Pascal, для выполнения этой задачи часто используется библиотека SuperObject. Однако, пользователи могут столкнуться с проблемами, когда вместо свойств классов в JSON попадают приватные переменные. В данной статье мы рассмотрим, как исправить данное поведение и добиться корректной сериализации свойств классов.
Описание проблемы
Рассмотрим код, который сериализует динамический массив классов. В коде используется библиотека SuperObject, которая по умолчанию сериализует приватные переменные, а не имена свойств классов. В результате получаем JSON, где ключами являются имена приватных переменных, а не свойств.
class function TJSON.AsJSON<T>(AObject: T; Indent: Boolean = False): string;
var
Ctx: TSuperRttiContext;
begin
Ctx := TSuperRttiContext.Create;
try
Result := Ctx.AsJson<T>(AObject).AsJSon(Indent);
finally
Ctx.Free;
end;
end;
type
TMyClass = class
private
FName_: String;
FAge_: Integer;
public
property Name: String read FName_ write FName_;
property Age: Integer read FAge_ write FAge_;
end;
При выполнении кода, который использует TJSON.AsJSON для сериализации массива объектов TMyClass, вместо ожидаемого JSON с ключами Name и Age получаем JSON с ключами FName_ и FAge_.
Ожидаемый JSON должен выглядеть следующим образом:
[{"Name":"Joe","Age":10},{"Name":"Dan","Age":13}]
Подтвержденный ответ
Проблема заключается в том, что по умолчанию SuperObject использует RTTI, которое работает с published свойствами. Чтобы исправить это поведение, необходимо изменить уровни доступа свойств с public на published. Это позволит сериализации использовать именно свойства классов, а не приватные переменные.
type
TMyClass = class
private
FName_: String;
FAge_: Integer;
published
property Name: String read FName_ write FName_;
property Age: Integer read FAge_ write FAge_;
end;
После внесения данного изменения, при сериализации объектов класса TMyClass с помощью TJSON.AsJSON будет получен корректный JSON с ключами Name и Age.
Альтернативный ответ
В случае, если изменение уровней доступа свойств на published по каким-то причинам не подходит, можно рассмотреть другие варианты, такие как использование записей (records) вместо классов, так как они могут обрабатываться сериализатором иначе.
Заключение
Использование published свойств в классе TMyClass позволяет корректно сериализовать объекты в JSON с использованием библиотеки SuperObject. Это базовое решение, которое позволяет избежать ошибок сериализации приватных переменных и получить ожидаемый формат JSON.
Проблема заключается в том, что при использовании библиотеки SuperObject для сериализации объектов в JSON в Delphi, по умолчанию сериализуются приватные переменные классов, а не их свойства, из-за чего в JSON оказываются имена приватных полей вместо назв
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS