Перейти к содержанию
  • Регистрация
  • 0
rareMax

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

Вопрос

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

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


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

Рекомендуемые сообщения

  • 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

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


Ссылка на сообщение
Поделиться на другие сайты
  • 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 и еще парочку 

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

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


Ссылка на сообщение
Поделиться на другие сайты
  • 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"}

 

Изменено пользователем Сысоев Максим

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


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

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

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


Ссылка на сообщение
Поделиться на другие сайты
  • 1
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

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


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

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

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

 

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


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

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

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

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

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


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

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

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

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

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

 

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


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

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

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

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


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

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

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

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


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

Для Syste,.JSON необходимо использовать атрибуты по типу которые расположены в REST.Json.Types

[JSONNameAttribute('НАЗВАНИЕ')] -Так ваша переменная назвается в JSON 

[JSONMarshalledAttribute(False)] - Так блокируется выгрузка (нащет загрузки не уверен) тоесть при TJsonObject(oJSON).ToString переменной с таким атрибутом не будет

TItems = class
  private
    [JSONNameAttribute('ERROR')]
    FERROR: String;
    [JSONNameAttribute('RESULT')]
    FRESULT: String;
    [JSONMarshalledAttribute(False)]
    FOwner : TItems;
  public
    property ERROR  : String read FERROR  write FERROR;
    property RESULT : String read FRESULT write FRESULT;
    property Owner  : TItems read FOwner  write FOwner;
  end;
  
 -------------Результат TJsonObject().ToString---------------------
 {"ERROR": "", "RESULT": ""}
 
 ==================================================================
 
 TItems = class
  private
    FERROR: String;
    FRESULT: String;
    FOwner : TItems;
  public
    property ERROR  : String read FERROR  write FERROR;
    property RESULT : String read FRESULT write FRESULT;
    property Owner  : TItems read FOwner  write FOwner;
  end;
  
 -------------Результат TJsonObject().ToString---------------------
 {"eRROR": "", "rESULT": "", "owner": ""} 

Если честно то не знаю почему так все используют XSuperObject, встроенного инструмента "System.JSON, REST.Json, REST.Json.Types" с головой хватает на всё 

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


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

XSO удобнее в 10 раз по синтаксису и не требует бесконечных приведений типов.

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


Ссылка на сообщение
Поделиться на другие сайты
  • 0
В 17.01.2018 в 07:55, krapotkin сказал:

XSO удобнее в 10 раз по синтаксису и не требует бесконечных приведений типов.

Может быть. Я обычно чтобы распарсить ответ от сервера, создаю класс и загружаю в него и уже потом работаю с классом (чего не умеет XSuperObject). Ну и как результат я не делаю приведение типов.

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


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

X:=TSuperObject.Create(json);

myObj.AssignFromJSON(X);

ну и загрузка-выгрузка в класс это не совсем работа с JSON

если он заменится на любой другой формат, мы и не узнаем...

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

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


Ссылка на сообщение
Поделиться на другие сайты
  • 0
В 18.01.2018 в 13:08, Виталий Иванов сказал:

Может быть. Я обычно чтобы распарсить ответ от сервера, создаю класс и загружаю в него и уже потом работаю с классом (чего не умеет XSuperObject). Ну и как результат я не делаю приведение типов.

Кто сказал что XSO этого не умеет?

и структуры и классы спокойно преобразовываются в обе стороны

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


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

Столкнулся со странным JSON-текстом.

Цитата

{
		labels: {
			ru: "Все для дома",
			by: "Усё для дома"
		},
		alias: {
			ru: "Для_дома_и_дачи",
			by: "Для_дома_і_дачы"
		},
		value: "3000",
		parent: null
	},

Приходит от сервера в виде javascript.

Обратите внимание, что у названий нет двойных кавычек.

Я так понимаю, что я должен  сделать демаршалинг этого json-текста? Это значит, что я должен знать правильную структуру объекта перед демаршалингом?

Спасибо.

 

Я просто с маршалингом ни разу ещё не сталкивался.

 

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


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

маршалинг и демаршалинг по определению привязаны к типу объекта

RTTI предоставляет список свойств и атрибутов и это все перегоняется в строку, передается по сети и восстанавливается из строки обратно на другом конце

при десериализации поле JSON должно записаться в поле объекта. если такого поля нет, очевидно будет ошибка.

Умеет ли XSO парсить новый JSON - не пробовал.

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


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

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.


  • Похожий контент

    • От rareMax
      Как убрать поле класса из сериализации через Rest.Json?
      Вот как я пробую избавиться от поля Foo:
      program Project1; {$APPTYPE CONSOLE} {$R *.res} uses REST.Json, System.JSON.Serializers, System.SysUtils; type TFoo = class private FValue1: Integer; public Value2: Integer; property Value3: Integer read FValue1 write FValue1; end; [JsonSerialize(TJsonMemberSerialization.&Public)] TBar = class private FValue1: Integer; FFoo: TFoo; public Value2: Integer; property Value3: Integer read FValue1 write FValue1; // property Foo: TFoo read FFoo write FFoo; end; procedure Test; var LBar: TBar; begin LBar := TBar.Create; try Writeln(TJson.ObjectToJsonString(LBar)); finally LBar.Free; end; end; begin try { TODO -oUser -cConsole Main : Insert code here } Test; Readln; except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; end. Но на выходе все равно есть поле Foo.
       
    • От 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:
      Как бы вы составили такой класс-прототип? Ведь тут получается в одном массиве есть как число так и строка.
    • От M1shQa
      Получаю с сервера большой 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
  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу

×
×
  • Создать...