• 0
rareMax

JSON Маршалинг/ДеМаршалинг в System.JSON

Вопрос

Поддерживает ли стандартная библиотека маршалинг/демаршалинг классов? Сейчас работаю с XSuperObject - работа очень приятная с ним. Но огорчает то, что тащит за собой тяжелые библиотеки(Инди, БД). Если нет - может кто знает альтернативы полегче? В идеале будет если так же будут Marshalling Attributes

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

18 ответов на этот вопрос

  • 1

Если я правильно понял, то https://github.com/magicxor/MXUtils/blob/master/Source/MX.MarshalManager.pas

Пример, в котором маршалится/анмаршалится объект типа TList<string>:https://github.com/magicxor/MXUtils/blob/master/Samples/MarshalManager/uFormMain.pas

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

XSuperObject  - это всего два файла

что куда она тащит??

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 1

для маршаллинга списков в XSO я использую. хитрый финт с объявлением fake-array-property и атрибутами [DISABLE] и [ALIAS('NAME')]

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
7 минут назад, krapotkin сказал:

XSuperObject  - это всего два файла

что куда она тащит??

unit XSuperObject;

interface

uses
  Classes,
  Variants,
  SysUtils,
  Character,
  XSuperJSON,
  RTTI,
  TypInfo,
  {X}DB,
  Generics.Collections,
  {X}IdGlobal,
  {X}IdCoderMIME;

Приходится линковать ИнДи в мой компонент, хотя я инди не использую. Впринципе не очень критично - но все же...

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

угу, посмотрел, раньше вроде не было этого

я думаю, это просто лень ему было написать тип PtrInt и еще парочку 

надо написать автору на гитхабе, он быстро исправляет ошибки

Равиль Зарипов (ZuBy) и Rusland понравилось это

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Стандартная библиотека поддерживает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Объясните в двух словах что такое маршалинг/демаршалинг классов?

Изменено пользователем Rusland

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Если правильно понимаю автор имеет ввиду TJSon.ObjectToJsonObject и TJSon.ObjectToJsonString. Как раз в стандартной библиотеке...

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Только есть один нюанс. В классе все свойства должны начинаться с буквы F. Если вы используете  классы с Сеттерами и Геттерами - то проблем быть не должно.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
1 час назад, Rusland сказал:

Объясните в двух словах что такое маршалинг/демаршалинг классов?

 

Вот я, например, работаю с ТелеграмБот АПИ. У него есть свои типы данных(если их так можно назвать).

К примеру тип User

Цитата

User

This object represents a Telegram user or bot.

Field Type Description
id Integer Unique identifier for this user or bot
first_name String User‘s or bot’s first name
last_name String Optional. User‘s or bot’s last name
username String Optional. User‘s or bot’s username

Когда вы запрашиваете какую то инфу с участием этого типа вам придет JSON с такими данными(в моем примере getMe):

Цитата

'{"ok":true,"result":{"id":122041176,"first_name":"Delphi in TelegAPI","username":"test_delphi_api_bot"}}'

В "result" будет как раз этот тип "User". Что бы не парсить отдельно каждое поле я создал аналогичный класс в делфи:

TTelegaUser = Class
  private
    FID: Integer;
    FFirstName: String;
    FLastName: String;
    FUsername: String;
  published
    /// <summary>
    /// Unique identifier for this user or bot
    /// </summary>
    /// <returns></returns>
    [ALIAS('id')]
    property ID: Integer read FID write FID;
    /// <summary>
    /// User‘s or bot’s first name
    /// </summary>
    [ALIAS('first_name')]
    property FirstName: String read FFirstName write FFirstName;
    /// <summary>
    /// Optional. User‘s or bot’s last name
    /// </summary>
    [ALIAS('last_name')]
    property LastName: String read FLastName write FLastName;
    /// <summary>
    /// Optional. User‘s or bot’s username
    /// </summary>
    [ALIAS('username')]
    property Username: String read FUsername write FUsername;
  End;

И теперь могу заполнить данными с моего запроса приблизительно так*:

FtelegUser := TTelegaUser.FromJSON(content);

* - На самом деле у меня чуть подругому.

* - При условии что в "content" у вас будет приблизительно такое содержание:

Цитата

{"id":122041176,"first_name":"Delphi in TelegAPI","username":"test_delphi_api_bot"}

 

Изменено пользователем Сысоев Максим
Rusland и Равиль Зарипов (ZuBy) понравилось это

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Кстати, если покажете как с моего примера, который выше, заменить XSuperObject на родную библиотеку JSON - буду очень благодарен

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 1

у родной нет таких клевых штук как alias('');

rareMax понравилось это

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
27 минут назад, krapotkin сказал:

у родной нет таких клевых штук как alias('');

Да, согласен. Но если автор хочет "родными", то выглядит это так:

type
  TTelegaUser = Class
  private
    FID: Integer;
    FFirst_Name: String;
    FLast_Name: String;
    FUsername: String;
  published
    property ID: Integer read FID write FID;
    property First_Name: String read FFirst_Name write FFirst_Name;
    property Last_Name: String read FLast_Name write FLast_Name;
    property Username: String read FUsername write FUsername;
  End;

.....


procedure TForm1.Button1Click(Sender: TObject);
var
  TelegaUser: TTelegaUser;
begin
  TelegaUser := TJson.JsonToObject<TTelegaUser>(MEMO1.Lines.Text);
end;
    
........    

В memo1 лежит ваш JSON

{"id":122041176,"first_name":"Delphi in TelegAPI","username":"test_delphi_api_bot"}

Важно чтобы у класса Свойства назывались точно так-же как в JSON.

Изменено пользователем Andy
Rusland и rareMax понравилось это

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Можно и без сеттеров и геттеров и тоже будет работать:

TTelegaUser = Class
    FID: Integer;
    FFirst_Name: String;
    FLast_Name: String;
    FUsername: String;
End;

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

конечно, любые public оно будет тянуть

просто вот у меня как-то нечасто объекты без вложенных внутри списков/массивов

а с этим уже не все так просто

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
2 минуты назад, krapotkin сказал:

конечно, любые public оно будет тянуть

просто вот у меня как-то нечасто объекты без вложенных внутри списков/массивов

а с этим уже не все так просто

Я передавал "родными" компонентами и вложенные массивы, и массивы классов - проблем не встретил

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

я в XE3 столкнулся с багами в сериализации и стал искать альтернативы. нашел XSO и успокоился )))

возможно, теперь все хорошо

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Автор поста задал вопрос... Надеюсь получил ответ... 

Можем закрывать?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте аккаунт или войдите для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!


Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.


Войти сейчас

  • Похожие публикации

    • Автор: ENERGY
      Друзья, нашел тут интересную статью, где тестируются разные jSON парсеры.
       
      Ссылка: http://www.webdelphi.ru/2016/10/ishhem-samyj-bystryj-parser-json-v-delphi/
      Автор: Владислав Баженов
      Описание (26/10/2016):
       
    • Автор: unicorn
      Всем привет. 
      Мне нужно отправить запрос к серверу в формате JSON-RPC. Вопрос - как в него запихнуть json-данные правильно?
    • Автор: Просто Проги
      Пытаюсь получить список друзей из вк получаю их по api записываю в memo.text ответ от get запроса,после пытаюсь получить из json поля
      ответ выглядит так
      { "response": { "count": 104, "items": [ { "id": 1308603, "first_name": "Виктория", "last_name": "Талина", "photo": "http://cs625517.vk.me/v625517603/4e79b/E9Q1WA5SSLiI.jpg", "photo_100": "http://cs625517.vk.me/v625517603/4e79a/15QwerpQbCKk.jpg", "photo_400_orig": "http://cs625517.vk.me/v625517603/4e7199/wxOJQyZhqq8.jpg", "online": 0 }, { "id": 282070, "first_name": "Никита", "last_name": "Багров", "photo": "http://cs630623.vk.me/v630623070/4b610/RXNNdJ6_Nik.jpg", "photo_100": "http://cs630623.vk.me/v630623070/4b60f/MDXpi0deY1A.jpg", "photo_400_orig": "http://cs630623.vk.me/v630623070/4b60e/ec7A3pBDJZ0.jpg", "online": 0 }, "first_name": "Имя ", Следующим кодом
       
      var JSON: TJSONObject; JSONArray: TJSONArray; i: Integer; begin JSON := TJSONObject.ParseJSONValue(Form2.Memo2.Lines.Text) as TJSONObject; сюда получается я заношу весь код Form2.Memo2.Lines.Clear; JSONArray := TJSONArray(JSON.Get('items').JsonValue); далее изу по массиву итмемов for i := 0 to JSONArray.Size - 1 do begin Form2.Memo2.Lines.Add(TJSONPair(TJSONObject(JSONArray.Get(i)).Get('first_name')).JsonValue.Value); пытаюсь добавить найденное поле end; но летят ошибка критичная (
    • Автор: rareMax
      Я работаю с библиотекой XSuperObject. Как правило, сам JSON я не парсю, а только создаю классы-прототипы данных в JSON, и пользуюсь методами .FromJSON и .ToJSON.
      пример:
      Для такого JSON'a 
      создаю такой класс:
      TvktStatus = Class private Ftext: String; FAudio: TvktAudio; published [Alias('text')] property text: String read Ftext write Ftext; [Alias('audio')] property audio: TvktAudio read FAudio write FAudio; End; в итоге не нужно парсить программисту - все делает библиотечка. 
      Теперь к самой проблеме.
      Допустим есть такой файлик с данными в формате JSON:
      Как бы вы составили такой класс-прототип? Ведь тут получается в одном массиве есть как число так и строка.
    • Автор: MikeWuzHere
      Получаю с сервера большой JSON, в нем есть поле number. Как получить список в memo состоящий только из номеров? Подскажите пожалуйста..
       
    • Автор: Dion
      Добрый день, Господа.
      Давайте меняться. 
      Предлагаю вам откуда-то взятый мною superobject, версии 1.2 из которой я выкинул разный хлам, допилил и сделал так, чтобы он собирался под Android, OS X и iOS. Протестировал.
      Дальше я написал вокруг него километр кода, создал набор стилей и сделал динамическую загрузку стилей для списка. В список в соответствии со стилями можно добавить порядка 20 разных компонентов.
      Идея моя была такой.
      Есть сервер, на него с клиента загружаются стили и дальше они разливаются от сервера к серверу и в конечном счете попадают на клиентов. Грубо говоря, должен получиться тонкий клиент.
      Надо кому? 
    • Автор: Axbor
      TJSONObject *o = dynamic_cast<TJSONObject*> (TJSONObject::ParseJSONValue(TEncoding::ASCII->GetBytes(s), 0)); if (!o) return; TJSONArray *a = dynamic_cast<TJSONArray*>(o->Get("M")->JsonValue); if (!a) return; for (int i = 0; i < a->Count; i++) { TJSONObject *b = dynamic_cast<TJSONObject*>(a->Get(i)); if (! return; Jokes[i + CurrPos].Caption = b->Pairs[0]->JsonValue->ToString(); Jokes[i + CurrPos].Content = b->Pairs[1]->JsonValue->ToString(); Count++; } delete L; L = 0;  "s" это текст которая хранит JSON внутри значений которого есть символ " (кавычка). В JONS е уже добавлены BackSlash перед такими символами. При парсинге JOSN опят добавляются BackSlash перед спец символами. Как от этого избежать?
    • Автор: Syb
      Я могу совсем что то не правильно делать, хочу получить данные согласно API :
       
       
      http://glonasssoft.ru/wiki/?wiki_name=API
      var jValue:TJSONValue; s,s1:string; begin RestClient1.BaseURL:='http://dev.glonasssoft.ru/auth/login'; Restrequest1.Execute; jValue:=RESTResponse1.JSONValue; s:=jValue.ToString; s1:= copy(s,pos('AuthID:"',s)+11,pos('","U',s)-pos('AuthID:"',s)-11);//достал ключ RestClient2.BaseURL:='http://dev.glonasssoft.ru/vehicles_'; Restrequest2.Params[0].Value:=s1; -здесь параметр типа HttpHeader задан X-Auth в него сую ключ Restrequest2.Execute; - говорит не авторезирован jValue:=RESTResponse2.JSONValue; s:=jValue.ToString; что я не так делаю?
    • Автор: Равиль Зарипов (ZuBy)
      Привет Всем!
       
      Решил поделится впечатлениями по работе с SuperObject'ом и родным JSON'ом
       
      тест был файла с 2000+ объектами в JSON файле
      структура файла была такая
      { "status":"OK", "last_id":"711", "objects":[ { "obj_id":"1", "obj_acc_id":"1", "obj_cat_id":"24", "obj_title":"13 магистраль", "obj_descr":"ЖК представляет собой комфортный дом, состоящий из 14 блок-секций (подъездов). Расположен в перспективном развивающемся районе по 13 Магистрали с удобным выездом как на левый берег, так и в старую часть города. Вблизи Жилого комплекса распологается новая школа, парк отдыха и культуры.", "obj_address":"ул. Мамышулы - 104, д. 16\/1", "obj_address2":null, "obj_url":"3fa07dd73be072b049529c80c7d74732", "obj_planet":"1", "obj_country":"1", "obj_region":"1", "obj_city":"292", "obj_lat":"51.141", "obj_lon":"71.4835", "obj_insert_dt":null, "obj_update_dt":null, "obj_editted":"0", "obj_updated":"0", "obj_deleted":"0", "obj_showed":"1", "obj_rating":"0", "obj_pro_top":"0", "obj_pro_selected":"0", "obj_pro_unix_dt":"0", "obj_partner":"0", "obj_parent_id":"0", "obj_has_child":"0", "obj_currency":"0" }, // тут далее 2000+ объектов ] } SuperObject  Время выполнения:  ~01:393
      JSON родной Время выполнения: ~01:690
       
      разница не особо ощутима, тем более если будет меньше объектов
       
      JSON родной
      function JSONParse(const aJSONData: string; const aMemo: TMemo): boolean; var aJSValue: TJSONValue; aJSObject, aJSObjArr: TJSONObject; aJSArray: TJSONArray; I: integer; begin Result := false; aJSValue := TJSONObject.ParseJSONValue(aJSONData) as TJSONValue; if Assigned(aJSValue) then begin aJSObject := aJSValue as TJSONObject; aMemo.Lines.Add('status: ' + aJSObject.GetValue('status').Value); if aJSObject.GetValue('status').Value = 'OK' then begin Result := true; if Assigned(aJSObject) then begin aJSArray := aJSObject.GetValue('objects') as TJSONArray; if Assigned(aJSArray) then begin Result := true; aMemo.Lines.Add('last_id: ' + aJSObject.GetValue('last_id').Value); aMemo.Lines.Add('count: ' + aJSArray.Count.ToString); for I := 0 to aJSArray.Count - 1 do begin aJSObjArr := aJSArray.Items[I] as TJSONObject; if Assigned(aJSObjArr) then begin aMemo.Lines.Add(aJSObjArr.GetValue('obj_id').Value + ',' + aJSObjArr.GetValue('obj_acc_id').Value + ',' + aJSObjArr.GetValue('obj_cat_id').Value); aMemo.Lines.Add(aJSObjArr.GetValue('obj_title').Value); aMemo.Lines.Add(aJSObjArr.GetValue('obj_descr').Value); aMemo.Lines.Add(aJSObjArr.GetValue('obj_address').Value); aMemo.Lines.Add(aJSObjArr.GetValue('obj_url').Value); end; end; end; end; end; aJSValue.Free; end; end; SuperObject
      function JSONSOParse(const aJSONData: string; const aMemo: TMemo): boolean; var xObject: ISuperObject; xCount, I: integer; sfmt: string; begin Result := false; xObject := SO(aJSONData); aMemo.Lines.Add('status: ' + xObject['status'].AsString); if xObject['status'].AsString = 'OK' then begin Result := true; xCount := xObject['objects'].AsArray.Length; aMemo.Lines.Add('count: ' + xCount.ToString); aMemo.Lines.Add('last_id: ' + xObject['last_id'].AsInteger.ToString); for I := 0 to xCount - 1 do begin aMemo.Lines.Add(xObject['objects[' + I.ToString + ']."obj_id"'].AsInteger.ToString + ',' + xObject['objects[' + I.ToString + ']."obj_acc_id"'].AsInteger.ToString + ',' + xObject['objects[' + I.ToString + ']."obj_cat_id"'].AsInteger.ToString); aMemo.Lines.Add(xObject['objects[' + I.ToString + ']."obj_title"'].AsString); aMemo.Lines.Add(xObject['objects[' + I.ToString + ']."obj_descr"'].AsString); aMemo.Lines.Add(xObject['objects[' + I.ToString + ']."obj_address"'].AsString); aMemo.Lines.Add(xObject['objects[' + I.ToString + ']."obj_url"'].AsString); end; end; end; Разница ощутима когда пишешь код, SO намного легче читать
       
      Подробней почитать и скачать SO
    • Автор: rareMax
      Необходимо распарсить JSON в котором есть массив. Искал в интернете - но там для сторонних библиотек. 
      Вот сам объект в котором есть массив:
      { "Version": "1", "Charset": "UTF-8", "Variables": { "cookiepre": "1ati_2132_", "auth": "2ab39ybBCy0KypS2Sh6Ey5facuaHGKSG/9uhrV0JHzcirqQX+fl2nFUErSIpvOwZJuGURxqrJ9arNTPGkIiZ", "saltkey": "C6bK667j", "member_uid": "3", "member_username": "Maximum", "groupid": "2", "formhash": "e2b42ccc", "ismoderator": null, "readaccess": "150", "notice": { "newpush": "0", "newpm": "0", "newprompt": "0", "newmypost": "0" }, "list": [ { "uid": "5", "username": "Player" }, { "uid": "12", "username": "RaR" }, { "uid": "29", "username": "prlzrak" }, { "uid": "63", "username": "Leemur" } ], "count": "4" } } Вот тут мне надо помощь с парсингом list.
  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу